Variable เป็นกลไกที่ทำให้ Terraform configuration สามารถนำกลับมาใช้ซ้ำได้ในหลายสภาพแวดล้อม เพราะค่าต่าง ๆ เช่น region, size, domain name ไม่ได้ถูก hardcode ลงในโค้ด แต่ส่งผ่านจากภายนอก ทำให้โปรเจกต์เดียวสามารถสร้าง dev ขนาดเล็กและ prod ขนาดใหญ่ได้โดยไม่ต้องแก้ไฟล์ .tf เลย การออกแบบ variable ที่ดีตั้งแต่แรกคือกุญแจของการทำ module ที่ยืดหยุ่น
บทความนี้จะอธิบายประเภทของ variable ใน Terraform การประกาศพร้อม type constraint และ validation การส่งค่าหลายวิธี และความแตกต่างของ input variable กับ output value ที่ผู้เริ่มต้นมักสับสน
ประกาศ Input Variable
Input variable ประกาศด้วย block variable ภายในไฟล์ (นิยมใส่ใน variables.tf) แต่ละตัวควรมี description, type และ default ถ้าเป็นไปได้ เพื่อให้ผู้ใช้งานเข้าใจวัตถุประสงค์และลดโอกาสผิดพลาดขณะส่งค่า
variable "region" {
description = "AWS region to deploy resources"
type = string
default = "ap-southeast-1"
}
variable "instance_count" {
description = "Number of worker instances"
type = number
default = 2
}
variable "enable_monitoring" {
description = "Enable detailed monitoring"
type = bool
default = false
}
variable "tags" {
description = "Common tags for all resources"
type = map(string)
default = {}
}
Type Constraint ที่ซับซ้อนขึ้น
นอกจาก primitive type, Terraform รองรับ structural type เช่น object และ tuple ที่ระบุรูปแบบข้อมูลได้ละเอียด เหมาะกับ variable ที่ต้องการกำหนด schema ให้ผู้ใช้ส่งค่าตามโครงสร้างที่วางไว้
variable "database" {
description = "Database configuration"
type = object({
engine = string
version = string
size = string
multi_az = bool
})
default = {
engine = "postgres"
version = "15.4"
size = "db.t3.small"
multi_az = false
}
}
variable "subnets" {
description = "List of subnet CIDRs"
type = list(string)
default = ["10.0.1.0/24", "10.0.2.0/24"]
}
Validation
Block validation ภายใน variable ช่วยตรวจสอบค่าที่ถูกส่งเข้ามา หากไม่ผ่านเงื่อนไข Terraform จะ fail ตั้งแต่ขั้น plan ก่อนสร้าง resource จริง ลดโอกาส apply ค่าที่ผิด
variable "environment" {
description = "Deployment environment"
type = string
validation {
condition = contains(["dev", "stage", "prod"], var.environment)
error_message = "environment ต้องเป็น dev, stage หรือ prod เท่านั้น"
}
}
variable "port" {
type = number
validation {
condition = var.port > 0 && var.port < 65536
error_message = "port ต้องอยู่ในช่วง 1-65535"
}
}
Sensitive Variable
หาก variable เก็บข้อมูลลับ เช่น password, token, secret key ให้ใส่ sensitive = true Terraform จะไม่แสดงค่านี้ใน plan/apply output และ output ที่ใช้ค่านี้ต่อก็จะถูกซ่อนโดยอัตโนมัติ
variable "db_password" {
description = "Database master password"
type = string
sensitive = true
}
วิธีส่งค่า Variable
Terraform รับค่า variable จากหลายแหล่งและมีลำดับความสำคัญชัดเจน แหล่งที่มาทีหลังจะทับค่าแหล่งก่อนหน้า
-var="name=value"ตอนรัน CLI-var-file="custom.tfvars"ชี้ไฟล์ .tfvars แบบกำหนดเอง- ไฟล์
*.auto.tfvarsและ*.auto.tfvars.jsonที่โหลดอัตโนมัติ - ไฟล์
terraform.tfvarsหรือterraform.tfvars.json - Environment variable ชื่อ
TF_VAR_ชื่อvar - Default value ใน block
variable
# terraform.tfvars
region = "us-east-1"
instance_count = 5
tags = {
Owner = "platform-team"
CostCenter = "R&D"
}
# รัน
terraform plan
terraform apply -var="region=ap-southeast-1"
terraform apply -var-file="prod.tfvars"
export TF_VAR_db_password="secret123"
terraform apply
Output Value
Output ใช้ export ค่าที่คำนวณได้หลัง apply ออกไปนอก module หรือไปแสดงที่ CLI เช่น IP address ของ EC2 ที่สร้างใหม่ endpoint ของ RDS หรือ URL ของ Load Balancer Output มีบทบาทสำคัญเมื่อ module ถูก consume โดย module อื่น เพราะเป็น interface ที่ caller อ่านได้
output "instance_public_ip" {
description = "Public IP of the web instance"
value = aws_instance.web.public_ip
}
output "db_connection_string" {
description = "Database connection string"
value = "postgres://${aws_db_instance.main.endpoint}/${var.db_name}"
sensitive = true
}
output "subnet_ids" {
value = aws_subnet.private[*].id
}
รัน terraform output หรือ terraform output subnet_ids เพื่อดูค่า ส่วนใน CI/CD pipeline สามารถ terraform output -json แล้ว parse ต่อได้สะดวก
Input vs Output ต่างกันอย่างไร
- Input variable = ค่าที่ ส่งเข้า configuration (ประกาศด้วย
variable) - Output value = ค่าที่ ส่งออก จาก configuration (ประกาศด้วย
output) - Input รู้ล่วงหน้า ก่อน apply / Output คำนวณได้หลัง apply
- ทั้งคู่รองรับ
description,sensitive, และtype - ใน module: input คือพารามิเตอร์ที่ caller ส่ง / output คือค่าที่ caller อ่านได้
สรุป
Variable และ Output ทำให้ configuration ของ Terraform เป็นสินค้าที่ขายต่อทีมอื่นได้ โดย input ช่วยให้ยืดหยุ่นต่อสภาพแวดล้อม และ output ช่วยให้ consumer ดึงค่าไปใช้ได้โดยไม่ต้องรู้ internal ของ module การประกาศ type constraint, validation, และ sensitive จะลดโอกาสผิดพลาดอย่างมาก เมื่อใช้คู่กับไฟล์ .tfvars ต่อ environment และ TF_VAR_ ใน CI/CD จะทำให้ pipeline จัดการ config ทั้งหมดอย่างเป็นระบบ ขั้นตอนถัดไปคือการรวบค่าที่คำนวณซ้ำ ๆ ไว้ใน local value เพื่อเขียน configuration ให้อ่านง่ายยิ่งขึ้น

