tfvars และการแยก Environment
📖 text • 10 นาทีtfvars และการแยก Environment
ปัญหา: Code เหมือนกัน แต่ค่าต่างกัน
Production กับ Development ใช้ resource เหมือนกัน แต่:
| Dev | Production | |
|---|---|---|
| Instance type | t2.micro |
t3.large |
| Instance count | 1 | 3 |
| Monitoring | off | on |
| Domain | dev.myapp.com | myapp.com |
ไม่ต้อง copy code — ใช้ tfvars file แยกค่าตาม environment
tfvars Files
terraform.tfvars — อ่านอัตโนมัติ
# terraform.tfvars
environment = "dev"
instance_type = "t2.micro"
instance_count = 1
*.auto.tfvars — อ่านอัตโนมัติ
# common.auto.tfvars
project = "myapp"
region = "ap-southeast-1"
Custom tfvars — ต้องระบุ flag
# environments/dev.tfvars
environment = "dev"
instance_type = "t2.micro"
instance_count = 1
monitoring = false
# environments/prod.tfvars
environment = "prod"
instance_type = "t3.large"
instance_count = 3
monitoring = true
# Deploy dev
terraform apply -var-file="environments/dev.tfvars"
# Deploy prod
terraform apply -var-file="environments/prod.tfvars"
โครงสร้างโปรเจค
my-project/
├── main.tf
├── variables.tf
├── outputs.tf
├── locals.tf
├── providers.tf
└── environments/
├── dev.tfvars
├── staging.tfvars
└── prod.tfvars
variables.tf
variable "environment" {
description = "Deployment environment (dev, staging, prod)"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t2.micro"
}
variable "instance_count" {
description = "Number of EC2 instances"
type = number
default = 1
}
variable "monitoring" {
description = "Enable detailed monitoring"
type = bool
default = false
}
locals.tf
locals {
name_prefix = "myapp-${var.environment}"
common_tags = {
Project = "myapp"
Environment = var.environment
ManagedBy = "terraform"
}
}
main.tf
resource "aws_instance" "web" {
count = var.instance_count
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
monitoring = var.monitoring
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-web-${count.index}"
})
}
Workspace vs tfvars
Terraform มี workspace สำหรับแยก state:
# สร้าง workspace
terraform workspace new dev
terraform workspace new prod
# สลับ workspace
terraform workspace select dev
# ดู workspace ปัจจุบัน
terraform workspace show
ใช้ใน code:
locals {
environment = terraform.workspace
}
เมื่อไรใช้อะไร?
| Approach | ข้อดี | ข้อเสีย |
|---|---|---|
| tfvars | ชัดเจน, explicit | ต้องจำ flag |
| Workspace | แยก state อัตโนมัติ | ซ่อน context, ลืมว่าอยู่ workspace ไหน |
แนะนำ: ใช้ tfvars + แยก state path สำหรับ production — ชัดเจนกว่า workspace
Priority Order
เมื่อค่าซ้ำกัน Terraform ใช้ค่าที่ priority สูงสุด:
1. default value ← ต่ำสุด
2. terraform.tfvars
3. *.auto.tfvars (alphabetical)
4. -var-file flag
5. TF_VAR_xxx environment variable
6. -var flag ← สูงสุด
ตัวอย่าง:
# variables.tf
variable "region" {
default = "ap-southeast-1" # priority 1
}
# terraform.tfvars
region = "us-east-1" # priority 2 — ชนะ default
terraform apply -var="region=eu-west-1" # priority 6 — ชนะทุกอัน
# ผลลัพธ์: region = "eu-west-1"
Best Practices
- ค่าที่ทุก env เหมือนกัน → ใส่ใน
default - ค่าที่ต่างตาม env → ใส่ใน
environments/*.tfvars - ค่าที่เป็นความลับ → ใช้ environment variables (
TF_VAR_xxx) - ไม่ commit
terraform.tfvarsที่มี secrets - ทำ template
terraform.tfvars.exampleให้ทีม
# terraform.tfvars.example (commit ได้)
environment = "" # dev, staging, prod
instance_type = "" # t2.micro, t3.large
db_password = "" # ใส่ค่าจริงตอน deploy
สรุป
| Concept | ตัวอย่าง |
|---|---|
| Auto-loaded | terraform.tfvars, *.auto.tfvars |
| Manual load | -var-file="prod.tfvars" |
| Env var | TF_VAR_name=value |
| CLI flag | -var="name=value" |
| Workspace | terraform workspace select prod |
| Priority | CLI flag > env var > var-file > auto.tfvars > tfvars > default |
บทถัดไปเรามา Lab สร้างโปรเจคที่ deploy ได้หลาย environment