Skip to main content

What is State?

State = ฐานข้อมูลที่ Terraform ใช้ track resource ที่จัดการอยู่ — เป็นหัวใจของ Terraform!

ทำไมต้องมี State?

Terraform ต้องรู้ว่า:

  • Resource ไหนที่ฉันสร้างไว้แล้ว?
  • Resource นั้นมี attribute อะไรบ้าง? (ID, ARN, IP)
  • Resource ไหนที่ต้องลบ (เพราะ user ลบจาก config)?

→ State = mapping ระหว่าง config กับ reality

State File: terraform.tfstate

หลัง terraform apply ครั้งแรก — Terraform สร้างไฟล์ terraform.tfstate ใน folder

my-project/
├── main.tf
├── variables.tf
├── terraform.tfstate # ← state file
├── terraform.tfstate.backup # ← backup จากครั้งก่อน
└── .terraform/

State File เป็น JSON

terraform.tfstate (excerpt)
{
"version": 4,
"terraform_version": "1.9.8",
"serial": 5,
"lineage": "abc-123-def",
"outputs": {
"bucket_name": {
"value": "my-data-bucket",
"type": "string"
}
},
"resources": [
{
"mode": "managed",
"type": "aws_s3_bucket",
"name": "data",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "my-data-bucket",
"arn": "arn:aws:s3:::my-data-bucket",
"bucket": "my-data-bucket",
"region": "ap-southeast-1",
"tags": {"Env": "prod"}
}
}
]
}
]
}
ห้าม edit state file ตรงๆ!
  • ใช้ Terraform commands (state mv, state rm) แทน
  • Edit ตรงๆ → corrupt state → infrastructure ไม่ตรง = disaster

State ใช้ทำอะไรบ้าง?

1. Track Resource Mapping

Config: aws_s3_bucket.data
State: aws_s3_bucket.data → ID = "my-data-bucket"

ถ้าไม่มี state → Terraform จะคิดว่าทุก resource ใน config = สร้างใหม่!

2. Cache Attributes

attribute "arn" = "arn:aws:s3:::my-data-bucket"

หลายครั้ง Terraform ไม่ต้องเรียก provider API ใหม่ — อ่านจาก state ได้เลย → เร็วขึ้น

3. Detect Drift

config.tags = {"Env" = "prod"}
state.tags = {"Env" = "prod", "Manual" = "ดึงเข้ามา"}

→ Terraform แสดงใน plan ว่ามี diff

4. Calculate Dependencies

aws_subnet.public depends on aws_vpc.main

State บันทึก dependency graph

5. Output Values

output.bucket_name = "my-data-bucket"

terraform output อ่านจาก state

State Lifecycle

Local State vs Remote State

Local State (default)

terraform.tfstate  ← อยู่ในเครื่อง local

✅ ข้อดี: ง่าย, ไม่ต้องตั้งค่า ❌ ข้อเสีย:

  • ทีมหลายคน → conflict
  • เครื่องพัง = state หาย
  • ไม่มี locking

Remote State (Production!)

terraform {
backend "s3" {
bucket = "my-tfstate"
key = "prod/terraform.tfstate"
region = "ap-southeast-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}

✅ ข้อดี:

  • ทีมแชร์ state ได้
  • มี locking
  • มี encryption
  • มี versioning

ดูเพิ่มใน Remote State

ข้อมูลใน State Sensitive!

State อาจเก็บ:

  • 🔑 Database passwords
  • 🔑 Private keys
  • 🔑 API tokens
  • 🔑 Auth credentials
"password": "mySuperSecret"   // plain text!
State Security
  • Encrypt — S3 + KMS
  • Limit access — IAM policy ที่จำกัด
  • Version — กู้คืนได้ถ้าผิดพลาด
  • ห้าม commit — ใส่ใน .gitignore

.gitignore ควรมี

.gitignore
# Local .terraform directories
.terraform/
.terraform.lock.hcl

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log
crash.*.log

# Sensitive variables
*.tfvars
!*.example.tfvars

# Override files
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Plan output
tfplan
*.tfplan

State Operations

# ดู resource ใน state
terraform state list

# ดู attribute ของ resource
terraform state show aws_s3_bucket.data

# Pull state ลง local (จาก remote)
terraform state pull > state.json

# Push state ขึ้น remote
terraform state push state.json

# Move resource ใน state
terraform state mv aws_instance.old aws_instance.new

# Remove resource จาก state (ไม่ลบ resource จริง)
terraform state rm aws_instance.old

# Replace resource (re-create ตอน apply ถัดไป)
terraform apply -replace="aws_instance.web"

ดูเพิ่มใน State Commands

ตัวอย่าง: ดู State

$ terraform state list
aws_s3_bucket.data
aws_instance.web
aws_security_group.web

$ terraform state show aws_s3_bucket.data
# aws_s3_bucket.data:
resource "aws_s3_bucket" "data" {
bucket = "my-data-bucket"
arn = "arn:aws:s3:::my-data-bucket"
id = "my-data-bucket"
region = "ap-southeast-1"
tags = {
"Environment" = "prod"
}
}

State Versioning

ทุกครั้งที่ apply — serial ใน state เพิ่ม:

{
"version": 4,
"serial": 15, # ← serial ของ apply
"lineage": "abc-123" # ← state ID (ไม่ควรเปลี่ยน)
}

ถ้าใช้ S3 backend + versioning → กู้ state version เก่าได้

สรุป

  • State = mapping ระหว่าง config กับ reality + cache attributes
  • ไฟล์ terraform.tfstate (JSON)
  • Local state ใช้สำหรับ dev/learning
  • Remote state (S3, GCS, etc.) สำหรับ production
  • State อาจมี secrets — encrypt + protect access
  • ห้าม commit state เข้า Git
  • ห้าม edit ไฟล์ state ตรงๆ — ใช้ terraform state commands

ต่อไป → Remote State