Basic Syntax
เรียน syntax พื้นฐานของ HCL — block, argument, expression, type — ครอบคลุมพอที่จะอ่าน Terraform code ส่วนใหญ่ออก
Anatomy ของ HCL File
# Comment ด้วย #
// Comment ด้วย //
/* Block comment
หลายบรรทัด */
# โครงพื้นฐานของ HCL = block
<BLOCK_TYPE> "<LABEL>" "<NAME>" {
<ARGUMENT> = <EXPRESSION>
<NESTED_BLOCK> {
...
}
}
1. Blocks
ทุกอย่างใน Terraform คือ block:
# Block พร้อม 2 labels
resource "aws_instance" "web" {
ami = "ami-12345"
}
# Block พร้อม 1 label
provider "aws" {
region = "ap-southeast-1"
}
# Block ไม่มี label
terraform {
required_version = ">= 1.0"
}
Block Types หลักใน Terraform
| Block | หน้าที่ |
|---|---|
terraform | ตั้งค่า Terraform เอง (version, backend) |
provider | ตั้งค่า provider (AWS, GCP, ...) |
resource | สร้าง infrastructure |
data | อ่านข้อมูลจาก provider |
variable | input variable |
output | output value |
locals | local values |
module | call a module |
2. Arguments
argument = key = value ใน block
resource "aws_instance" "web" {
ami = "ami-12345" # string
instance_type = "t2.micro" # string
count = 3 # number
monitoring = true # bool
tags = { # map
Name = "web"
}
}
Style
Terraform formatter (terraform fmt) จะจัด = ให้ตรงกัน — ไม่ต้องจัดเอง
3. Types พื้นฐาน
Primitive
name = "alice" # string
age = 30 # number
is_active = true # bool
Collection
# List (ordered)
fruits = ["apple", "banana", "orange"]
# Set (unique, unordered)
tags = toset(["dev", "test"])
# Map (key-value)
person = {
name = "Alice"
age = 30
}
Structural
# Object (typed key-value)
user = {
name = "Alice"
email = "[email protected]"
age = 30
}
# Tuple (typed list)
record = ["Alice", 30, true]
Null
optional_field = null
4. Expressions
String Interpolation ${...}
locals {
full_name = "${var.first_name} ${var.last_name}"
hello = "Hello, ${upper(var.name)}!"
}
Old style
เลิกใช้ "${var.x}" ถ้าอ้างอิงตัวเดียว — ใช้ var.x ตรงๆ
# ❌ ของเก่า
name = "${var.name}"
# ✅ แบบใหม่
name = var.name
Arithmetic
total = 10 + 5 * 2 # 20
modulo = 7 % 3 # 1
Comparison & Logical
is_prod = var.env == "prod" # ==, !=
is_big = var.size > 100 # >, <, >=, <=
is_active = var.enabled && !var.dry_run # &&, ||, !
Conditional (Ternary)
instance_type = var.env == "prod" ? "t3.large" : "t3.micro"
For Expression
# List comprehension
upper_names = [for name in var.names : upper(name)]
# Map comprehension
name_to_age = {for u in var.users : u.name => u.age}
# Filter
adults = [for u in var.users : u if u.age >= 18]
Splat Expression [*]
# เอา id ของทุก instance
ids = aws_instance.web[*].id
5. References
อ้างอิง resource อื่นด้วย dot notation:
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # ← reference!
cidr_block = "10.0.1.0/24"
}
Reference Patterns
| ที่ใช้ | Syntax |
|---|---|
| Resource attribute | aws_vpc.main.id |
| Variable | var.region |
| Local | local.full_name |
| Module output | module.network.vpc_id |
| Data source | data.aws_ami.ubuntu.id |
| Path info | path.module, path.root |
| Workspace | terraform.workspace |
6. Functions
HCL มี built-in functions เยอะมาก — ตัวที่ใช้บ่อย:
# String
upper("hello") # "HELLO"
lower("WORLD") # "world"
length("abc") # 3
substr("hello", 0, 3) # "hel"
# Numeric
max(1, 2, 3) # 3
min(1, 2, 3) # 1
# Collection
length([1, 2, 3]) # 3
contains(["a", "b"], "a") # true
keys({a=1, b=2}) # ["a", "b"]
values({a=1, b=2}) # [1, 2]
merge({a=1}, {b=2}) # {a=1, b=2}
# Encoding
jsonencode({a=1}) # "{\"a\":1}"
yamlencode({a=1})
# File
file("user-data.sh") # อ่านไฟล์
templatefile("init.tpl", {name="alice"})
# Type conversion
tostring(123) # "123"
tonumber("42") # 42
toset([1, 2, 2]) # [1, 2]
ดู built-in functions ทั้งหมดที่ Terraform Language Functions
7. Heredoc Strings (Multi-line)
user_data = <<-EOF
#!/bin/bash
apt update
apt install -y nginx
systemctl start nginx
EOF
<<-EOF (มี dash) = ตัด indent หน้าซ้ายให้อัตโนมัติ
<<EOF (ไม่มี dash) = เก็บ indent ไว้ตามที่เขียน
8. Comments
# แบบ shell-style (แนะนำ)
// แบบ C-style
/* Multi-line
comment */
terraform fmt จะแปลง // → # ให้อัตโนมัติ
ตัวอย่าง: รวมทุกอย่าง
main.tf
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.region
}
variable "region" {
type = string
default = "ap-southeast-1"
}
variable "environment" {
type = string
default = "dev"
}
locals {
name_prefix = "${var.environment}-app"
common_tags = {
Environment = var.environment
ManagedBy = "terraform"
}
}
resource "aws_s3_bucket" "data" {
bucket = "${local.name_prefix}-data-bucket"
tags = local.common_tags
}
output "bucket_arn" {
value = aws_s3_bucket.data.arn
}
สรุป
- Block = building block พื้นฐาน —
<TYPE> "<LABEL>" {...} - Argument =
key = value - Types: primitive (string/number/bool), collection (list/set/map), structural (object/tuple)
- Expression: interpolation
${...}, conditional? :, for[for x in ... : ...], splat[*] - Reference:
aws_vpc.main.id,var.x,local.x,module.x.y - Function: เยอะมาก — เริ่มจาก
length, upper, jsonencode, file