Terraform Locals: จัดกลุ่ม Configuration Values

Local value หรือ locals block ใน Terraform คือกลไกสำหรับตั้งชื่อให้กับนิพจน์หรือค่าที่คำนวณได้ เพื่อใช้งานซ้ำในหลายจุดของ configuration หากเคยเขียน programming มาก่อน locals เทียบได้กับ constant หรือ helper variable ภายในฟังก์ชัน ต่างจาก input variable ตรงที่ผู้ใช้จากภายนอก ไม่สามารถ เปลี่ยนค่าของ locals ได้ ค่ามันคำนวณภายใน module เท่านั้น

บทความนี้จะอธิบายวิธีประกาศ locals, กรณีใช้งานที่เหมาะสม, ความแตกต่างระหว่าง locals กับ variable และตัวอย่างการใช้ locals เพื่อทำให้ configuration อ่านง่ายและ maintain ได้ดียิ่งขึ้น

ประกาศ Locals Block

Locals ประกาศใน block เดียวชื่อ locals ภายในนั้นใส่ key-value ได้หลายตัว และเรียกใช้งานผ่าน local.ชื่อ (สังเกตว่าเป็น local ไม่ใช่ locals ตอนอ้างอิง)

locals {
  project_name = "myapp"
  environment  = "production"
  region       = "ap-southeast-1"

  common_tags = {
    Project     = "myapp"
    Environment = "production"
    ManagedBy   = "terraform"
  }
}

resource "aws_s3_bucket" "assets" {
  bucket = "${local.project_name}-assets-${local.environment}"
  tags   = local.common_tags
}

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

  • ค่าที่ใช้ซ้ำในหลาย resource เช่น ชื่อโปรเจกต์, tag set, naming convention
  • นิพจน์ที่ซับซ้อนและอ่านยาก เช่น การรวม string หรือ transform list → map
  • ค่าที่คำนวณจาก variable หลายตัว เพื่อไม่ให้ต้องเขียนซ้ำทุกครั้ง
  • Mapping/lookup table ที่ใช้ภายใน module เท่านั้น

Locals ทำงานกับ Expression ได้หลากหลาย

ค่าของ local ไม่จำเป็นต้องเป็น literal เท่านั้น สามารถใช้ expression, function และอ้างอิง variable/resource อื่นได้

variable "environment" {
  type = string
}

variable "owner" {
  type    = string
  default = "platform-team"
}

locals {
  # รวม tag จาก variable + fixed value
  common_tags = merge(
    {
      Environment = var.environment
      Owner       = var.owner
      ManagedBy   = "terraform"
    },
    var.extra_tags,
  )

  # คำนวณชื่อ bucket จาก environment + random suffix
  bucket_name = "logs-${var.environment}-${substr(md5(var.environment), 0, 6)}"

  # map ของ instance type ตาม environment
  instance_type_map = {
    dev   = "t3.micro"
    stage = "t3.small"
    prod  = "t3.medium"
  }

  instance_type = local.instance_type_map[var.environment]
}

Locals vs Variable vs Output

  • Variable = input จากผู้ใช้ → เปลี่ยนได้ตอน plan/apply
  • Local = ค่าคำนวณภายใน module → ผู้ใช้จากภายนอกแก้ไม่ได้
  • Output = ค่าที่ export ให้ caller อ่าน → ใช้หลัง apply

หลักง่าย ๆ คือ ถ้าค่าต้องปรับเปลี่ยนได้ตามสภาพแวดล้อม ใช้ variable ถ้าค่าเป็น “สูตร” ที่คำนวณซ้ำ ๆ ใช้ locals ถ้าอยากให้ module อื่นหรือ caller เห็น ใช้ output

ตัวอย่าง: ลดการเขียนซ้ำด้วย Locals

เปรียบเทียบโค้ดก่อนและหลังใช้ locals ในบทบาทของ tag management

# ก่อนใช้ locals — เขียนซ้ำทุก resource
resource "aws_instance" "web" {
  ami           = "ami-123"
  instance_type = "t3.micro"
  tags = {
    Project     = "myapp"
    Environment = var.environment
    Owner       = "platform-team"
    ManagedBy   = "terraform"
  }
}

resource "aws_s3_bucket" "assets" {
  bucket = "assets"
  tags = {
    Project     = "myapp"
    Environment = var.environment
    Owner       = "platform-team"
    ManagedBy   = "terraform"
  }
}

# หลังใช้ locals
locals {
  common_tags = {
    Project     = "myapp"
    Environment = var.environment
    Owner       = "platform-team"
    ManagedBy   = "terraform"
  }
}

resource "aws_instance" "web" {
  ami           = "ami-123"
  instance_type = "t3.micro"
  tags          = local.common_tags
}

resource "aws_s3_bucket" "assets" {
  bucket = "assets"
  tags   = local.common_tags
}

สรุป

Locals เป็นเครื่องมือพื้นฐานที่ทำให้ configuration ของ Terraform อ่านง่ายและบำรุงรักษาได้ ด้วยการรวบนิพจน์ซ้ำ ๆ ไว้จุดเดียว ใช้ได้ดีกับ tag รวม, naming pattern, lookup map, และการแปลงข้อมูลจาก variable หลายตัว จุดสำคัญคือ locals ไม่ใช่ input จากภายนอกและไม่ถูก export ออก ใช้สำหรับ internal logic ภายใน module เท่านั้น เมื่อเขียนบทความหรือ module ที่ซับซ้อนขึ้น การใช้ locals ควบคู่กับ variable และ output จะช่วยให้โครงสร้าง configuration ยืดหยุ่นและชัดเจนยิ่งขึ้น