Terraform Workspace: แยก State ต่อ Environment ในโปรเจกต์เดียว

โปรเจกต์ infrastructure ส่วนใหญ่ต้องรองรับหลาย environment เช่น dev, stage และ prod ในขณะเดียวกัน แต่ละ environment ก็ไม่ควรแชร์ state file เดียวกัน มิฉะนั้นการ apply ใน dev อาจกระทบ prod โดยไม่ตั้งใจ Workspace เป็นกลไกที่ช่วยแยก state ภายใน backend เดียวกันโดยไม่ต้อง copy code ทั้งชุด

บทความนี้จะอธิบายความแตกต่างระหว่าง CLI workspace และ directory-per-environment, คำสั่งพื้นฐาน, ข้อดี-ข้อเสีย และกรณีใช้งานที่เหมาะสมของแต่ละแนวทาง

Workspace คืออะไร

Workspace เป็น namespace ภายใน state file เดียว ทุก workspace ใช้ configuration เดียวกันแต่เก็บ state แยกกัน ค่าเริ่มต้นของโปรเจกต์คือ workspace ชื่อ default เมื่อสร้าง workspace ใหม่ Terraform จะเก็บ state ในพาธที่มีชื่อ workspace ต่อท้าย

# ดู workspace ปัจจุบัน
terraform workspace show

# สร้าง workspace ใหม่ (ทำซ้ำสำหรับ staging, prod)
terraform workspace new dev

# สลับ workspace
terraform workspace select prod

# แสดงทุก workspace
terraform workspace list

# ลบ workspace (ต้องไม่ใช่ตัวปัจจุบัน และ state ต้องว่าง)
terraform workspace delete dev

อ้างอิงชื่อ Workspace ใน Configuration

ภายใน configuration ใช้ terraform.workspace เพื่อดึงชื่อ workspace ปัจจุบัน ทำให้ปรับค่าแบบ dynamic ได้โดยไม่ต้องสร้าง variable ซ้ำ

locals {
  instance_sizes = {
    default = "t3.micro"
    dev     = "t3.micro"
    staging = "t3.small"
    prod    = "t3.large"
  }

  min_sizes = {
    default = 1
    dev     = 1
    staging = 2
    prod    = 3
  }
}

resource "aws_instance" "web" {
  instance_type = local.instance_sizes[terraform.workspace]
  tags = {
    Environment = terraform.workspace
  }
}

resource "aws_autoscaling_group" "web" {
  name     = "${terraform.workspace}-web-asg"
  min_size = local.min_sizes[terraform.workspace]
  max_size = local.min_sizes[terraform.workspace] * 3
}

CLI Workspace vs Directory-per-Environment

วิธีจัดการ environment หลักมี 2 แนวทาง ทั้งสองอย่างใช้กันแพร่หลาย เลือกตามขนาดและความซับซ้อนของโปรเจกต์

# แบบที่ 1: CLI workspace (state แยก แต่ code ชุดเดียว)
project/
├── main.tf
├── variables.tf
└── backend.tf

# backend เก็บ state ทุก workspace
# s3://bucket/env:/dev/terraform.tfstate
# s3://bucket/env:/prod/terraform.tfstate

# แบบที่ 2: Directory per environment (แยก code + state)
project/
├── modules/
│   └── web/
├── dev/
│   ├── main.tf
│   ├── terraform.tfvars
│   └── backend.tf
├── staging/
└── prod/
  • CLI workspace — ข้อดีคือ code ชุดเดียว, อัพเดตใน environment เดียวก็ปรับทุก environment ตามได้ทันที ข้อเสียคือใช้ backend เดียวกัน กระทบถึงกันได้ถ้า config ผิด
  • Directory-per-environment — ข้อดีคือแยก blast radius ชัดเจน ทดลองใน dev โดยไม่กระทบ prod ข้อเสียคือ duplicate code บางส่วน

เมื่อไรควรใช้ Workspace

Workspace เหมาะกับกรณีที่ environment มีโครงสร้างคล้ายกันมาก เช่น dev/stage/prod ที่ใช้ resource แบบเดียวกันเพียงต่างขนาด แต่ถ้าแต่ละ environment มี feature ไม่เหมือนกัน (เช่น prod มี DR, stage ไม่มี) ควรแยก directory จะจัดการง่ายกว่า

  • ใช้ workspace เมื่อ: โครงสร้างเหมือนกัน, ต่างแค่ค่าแปรผัน (size, count)
  • ใช้ directory เมื่อ: resource set ต่างกัน, มี feature flag ต่างกัน, ต้อง approval separate
  • ไม่ใช้ workspace สำหรับแยก account/region ที่มีอำนาจ access ต่างกัน เพราะ state อยู่ bucket เดียว

Terraform Cloud Workspace

คำว่า workspace ใน Cloud/Enterprise edition มีความหมายกว้างกว่า CLI workspace ใน OSS คือเป็น unit ของ run/state/variable/permission แยกกันเต็มรูปแบบ เทียบได้กับ “ทั้งหนึ่งโปรเจกต์” ของ CLI workspace รวมกับ access control ระดับ workspace

  • แต่ละ workspace มี variable set, environment variable และ run history ของตัวเอง
  • มี VCS integration — ผูกกับ branch/directory ของ Git repo
  • สามารถตั้ง trigger ให้ apply อัตโนมัติหรือต้อง approve ก่อน

สรุป

Workspace ใน CLI ช่วยแยก state file ต่อ environment ในขณะที่ code ยังคงเป็นชุดเดียว เหมาะกับ environment ที่โครงสร้างคล้ายกัน การใช้ terraform.workspace ร่วมกับ map ทำให้ปรับค่าแตกต่างกันได้ แต่เมื่อ environment ต้องการความแตกต่างที่ใหญ่กว่านั้น การแยก directory จะปลอดภัยและจัดการง่ายกว่า ในโลกของ Terraform Cloud คำว่า workspace มีบทบาทเป็น unit เต็มรูปแบบพร้อม permission และ run history ในบทความถัดไปจะลงลึกเรื่องการจัดการ state file และ backend สำหรับ production