Skip to main content

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
variableinput variable
outputoutput value
localslocal values
modulecall 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 attributeaws_vpc.main.id
Variablevar.region
Locallocal.full_name
Module outputmodule.network.vpc_id
Data sourcedata.aws_ami.ubuntu.id
Path infopath.module, path.root
Workspaceterraform.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

ต่อไป → Section 3: Providers & Initialization