Terraform State Management สอนจัดการ State File อย่างปลอดภัยสำหรับทีม 2026

Terraform State คืออะไร? ทำไมถึงสำคัญมาก?

Terraform State คือไฟล์ที่ Terraform ใช้บันทึกสถานะปัจจุบันของ Infrastructure ทั้งหมดที่ Terraform จัดการอยู่ เมื่อคุณรัน terraform apply ครั้งแรก Terraform จะสร้าง Resource ตาม Configuration แล้วบันทึกข้อมูลทั้งหมดลงในไฟล์ terraform.tfstate ในรูปแบบ JSON

ทำไม State ถึงสำคัญ? เพราะ Terraform ต้อง เปรียบเทียบ ระหว่างสิ่งที่เขียนไว้ใน Code (Desired State) กับสิ่งที่มีอยู่จริงใน Cloud (Actual State) ถ้าไม่มี State file Terraform จะไม่รู้ว่า Resource ไหนเคยสร้างไว้แล้ว จะสร้างซ้ำทุกครั้ง ทำให้เกิด Duplicate resource และค่าใช้จ่ายพุ่ง

ข้อมูลที่ State เก็บ

  • Resource Mapping: จับคู่ระหว่าง Resource ใน Code กับ Resource ID จริงใน Cloud
  • Metadata: ข้อมูล Dependencies ระหว่าง Resource
  • Performance Cache: เก็บ Attribute ของ Resource ไว้ ไม่ต้อง Query Cloud ทุกครั้ง
  • Sensitive Data: Password, API Keys, Connection Strings ที่ใช้ตอนสร้าง Resource
# ดูตัวอย่าง State file
cat terraform.tfstate | jq '.resources[0]'
{
  "mode": "managed",
  "type": "aws_instance",
  "name": "web_server",
  "provider": "provider["registry.terraform.io/hashicorp/aws"]",
  "instances": [
    {
      "attributes": {
        "id": "i-0abc123def456789",
        "ami": "ami-0c55b159cbfafe1f0",
        "instance_type": "t3.medium",
        "public_ip": "54.123.45.67",
        "private_ip": "10.0.1.100",
        "tags": { "Name": "web-server-prod" }
      }
    }
  ]
}

Local State vs Remote State

โดยค่าเริ่มต้น Terraform เก็บ State ไว้ใน Local file ชื่อ terraform.tfstate บนเครื่องที่รัน Terraform ซึ่งมีปัญหาหลายอย่าง:

เรื่อง Local State Remote State
ที่เก็บ ไฟล์บนเครื่อง S3, Azure Blob, GCS, Terraform Cloud
ทีมทำงานร่วมกัน ทำไม่ได้ดี ต้องส่งไฟล์กัน ทุกคนเข้าถึง State เดียวกัน
State Locking ไม่มี มี (ป้องกัน Conflict)
Version History ไม่มี มี (S3 Versioning)
Encryption ไม่มี (Plaintext) มี (SSE-S3, SSE-KMS)
Backup ต้องทำเอง อัตโนมัติ
เหมาะกับ ทดลอง/คนเดียว ทีม/Production

กฎเหล็ก: ถ้าทำงานเป็นทีม หรือ Infrastructure สำคัญ ต้องใช้ Remote State เสมอ ไม่มีข้อยกเว้น

S3 + DynamoDB Backend — มาตรฐานสำหรับ AWS

การใช้ S3 เก็บ State file ร่วมกับ DynamoDB สำหรับ State Locking เป็นรูปแบบที่นิยมที่สุดในโลก AWS:

ขั้นตอนที่ 1: สร้าง S3 Bucket และ DynamoDB Table

# สร้าง S3 Bucket สำหรับเก็บ State
aws s3api create-bucket   --bucket my-terraform-state-prod   --region ap-southeast-1   --create-bucket-configuration LocationConstraint=ap-southeast-1

# เปิด Versioning (สำคัญมาก!)
aws s3api put-bucket-versioning   --bucket my-terraform-state-prod   --versioning-configuration Status=Enabled

# เปิด Encryption
aws s3api put-bucket-encryption   --bucket my-terraform-state-prod   --server-side-encryption-configuration '{
    "Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "aws:kms"}}]
  }'

# ปิด Public Access
aws s3api put-public-access-block   --bucket my-terraform-state-prod   --public-access-block-configuration   "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

# สร้าง DynamoDB Table สำหรับ State Locking
aws dynamodb create-table   --table-name terraform-state-lock   --attribute-definitions AttributeName=LockID,AttributeType=S   --key-schema AttributeName=LockID,KeyType=HASH   --billing-mode PAY_PER_REQUEST

ขั้นตอนที่ 2: กำหนด Backend ใน Terraform

# backend.tf
terraform {
  backend "s3" {
    bucket         = "my-terraform-state-prod"
    key            = "prod/infrastructure/terraform.tfstate"
    region         = "ap-southeast-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"

    # (Optional) KMS Key สำหรับ Encryption
    # kms_key_id = "arn:aws:kms:ap-southeast-1:123456789:key/abc-123"
  }
}

# Initialize backend
# terraform init

ขั้นตอนที่ 3: Migrate จาก Local ไป Remote

# ถ้ามี State อยู่แล้ว ต้อง Migrate
terraform init -migrate-state

# Terraform จะถาม:
# "Do you want to copy existing state to the new backend?"
# ตอบ yes

# ตรวจสอบว่า State ไปถึง S3 แล้ว
aws s3 ls s3://my-terraform-state-prod/prod/infrastructure/

# ลบ Local state (หลัง Migrate สำเร็จแล้ว)
rm terraform.tfstate terraform.tfstate.backup

Azure Blob Backend

สำหรับคนที่ใช้ Azure การเก็บ State ใน Azure Blob Storage มีข้อดีคล้ายกับ S3:

# สร้าง Resource Group + Storage Account
az group create --name rg-terraform-state --location southeastasia

az storage account create   --name tfstateaccount2026   --resource-group rg-terraform-state   --location southeastasia   --sku Standard_LRS   --encryption-services blob

# สร้าง Container
az storage container create   --name tfstate   --account-name tfstateaccount2026   --auth-mode login

# Backend Configuration
terraform {
  backend "azurerm" {
    resource_group_name  = "rg-terraform-state"
    storage_account_name = "tfstateaccount2026"
    container_name       = "tfstate"
    key                  = "prod.terraform.tfstate"
  }
}

# Azure Blob มี Built-in Locking ผ่าน Blob Lease
# ไม่ต้องสร้าง Table แยกเหมือน AWS DynamoDB

GCS (Google Cloud Storage) Backend

# สร้าง Bucket
gsutil mb -l asia-southeast1 gs://my-terraform-state-prod

# เปิด Versioning
gsutil versioning set on gs://my-terraform-state-prod

# Backend Configuration
terraform {
  backend "gcs" {
    bucket = "my-terraform-state-prod"
    prefix = "terraform/state"
  }
}

# GCS มี Built-in Locking ไม่ต้องตั้งค่าเพิ่ม

State Locking — ป้องกัน Concurrent Access

State Locking คือกลไกที่ป้องกันไม่ให้คนสองคน (หรือ CI/CD สอง Pipeline) แก้ไข State พร้อมกัน ซึ่งอาจทำให้เกิด State corruption หรือ Resource conflict

วิธีการทำงานของ State Locking

  1. เมื่อรัน terraform plan หรือ terraform apply Terraform จะพยายาม Lock State
  2. ถ้า Lock สำเร็จ → ดำเนินการต่อ
  3. ถ้า Lock ไม่สำเร็จ (มีคนอื่นกำลังใช้) → แสดง Error และรอ
  4. เมื่อเสร็จ → ปลด Lock อัตโนมัติ
# เมื่อเจอ Lock error:
# Error: Error acquiring the state lock
# Lock Info:
#   ID:        a1b2c3d4-e5f6-7890
#   Path:      prod/infrastructure/terraform.tfstate
#   Operation: OperationTypeApply
#   Who:       john@macbook
#   Created:   2026-04-16 10:30:00

# ถ้ามั่นใจว่า Lock ค้าง (คนนั้นยกเลิกไปแล้ว) สามารถ Force unlock:
terraform force-unlock a1b2c3d4-e5f6-7890

# คำเตือน: ใช้ force-unlock เฉพาะเมื่อมั่นใจว่าไม่มีใครกำลังใช้อยู่จริงๆ!

State Splitting — แยก State ตาม Environment และ Service

เมื่อ Infrastructure ใหญ่ขึ้น การเก็บทุกอย่างใน State เดียวมีปัญหา: ช้า, เสี่ยงสูง, ทีมชนกัน ทางออกคือ State Splitting

แยกตาม Environment

# โครงสร้างไดเรกทอรี
infrastructure/
├── modules/
│   ├── vpc/
│   ├── ec2/
│   ├── rds/
│   └── s3/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── backend.tf    # key = "dev/terraform.tfstate"
│   ├── staging/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── backend.tf    # key = "staging/terraform.tfstate"
│   └── prod/
│       ├── main.tf
│       ├── variables.tf
│       └── backend.tf    # key = "prod/terraform.tfstate"

# แต่ละ Environment มี State แยกกัน
# Apply dev ไม่กระทบ prod

แยกตาม Service/Layer

# แยก State ตาม Layer
infrastructure/
├── network/          # VPC, Subnet, NAT Gateway
│   └── backend.tf    # key = "prod/network/terraform.tfstate"
├── database/         # RDS, ElastiCache
│   └── backend.tf    # key = "prod/database/terraform.tfstate"
├── compute/          # EC2, ECS, Lambda
│   └── backend.tf    # key = "prod/compute/terraform.tfstate"
├── monitoring/       # CloudWatch, SNS
│   └── backend.tf    # key = "prod/monitoring/terraform.tfstate"

# ใช้ terraform_remote_state Data Source เพื่ออ่านข้อมูลข้าม State
data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "my-terraform-state-prod"
    key    = "prod/network/terraform.tfstate"
    region = "ap-southeast-1"
  }
}

# ใช้ Output จาก Network State
resource "aws_instance" "web" {
  subnet_id = data.terraform_remote_state.network.outputs.public_subnet_id
  # ...
}

Terraform Workspaces (ทางเลือก)

# Workspace ช่วยแยก State ในโปรเจกต์เดียว
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod

# สลับ Workspace
terraform workspace select prod

# ดู Workspace ทั้งหมด
terraform workspace list

# ใช้ Workspace ใน Code
resource "aws_instance" "web" {
  instance_type = terraform.workspace == "prod" ? "t3.large" : "t3.micro"
  tags = {
    Environment = terraform.workspace
  }
}

# ข้อจำกัดของ Workspace:
# - ใช้ Backend เดียวกัน เปลี่ยน Access control ยาก
# - ไม่เหมาะถ้า Environment แตกต่างกันมาก
# - แนะนำใช้ Directory-based splitting แทนสำหรับ Production

terraform import — นำ Resource ที่มีอยู่แล้วเข้า State

terraform import ใช้สำหรับนำ Resource ที่สร้างด้วยมือ (หรือเครื่องมืออื่น) เข้ามาอยู่ใน Terraform State:

# ขั้นตอนที่ 1: เขียน Resource block ใน .tf ก่อน
resource "aws_instance" "existing_web" {
  # เขียน Config ให้ตรงกับ Resource ที่มีอยู่จริง
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"
  subnet_id     = "subnet-abc123"
  tags = {
    Name = "existing-web-server"
  }
}

# ขั้นตอนที่ 2: Import
terraform import aws_instance.existing_web i-0abc123def456789

# ขั้นตอนที่ 3: ตรวจสอบด้วย plan
terraform plan
# ถ้ามี diff ต้องแก้ไข .tf ให้ตรงกับ Resource จริง
# เป้าหมาย: terraform plan แสดง "No changes"

# Import Block (Terraform 1.5+) — วิธีใหม่ที่ดีกว่า
import {
  to = aws_instance.existing_web
  id = "i-0abc123def456789"
}

# สร้าง Config อัตโนมัติ
terraform plan -generate-config-out=generated.tf

terraform state mv / rm — ย้ายและลบ Resource จาก State

# ย้าย Resource ใน State (เปลี่ยนชื่อ)
terraform state mv aws_instance.old_name aws_instance.new_name

# ย้าย Resource ไป Module
terraform state mv aws_instance.web module.web.aws_instance.main

# ย้าย Resource ข้าม State
terraform state mv -state-out=../other/terraform.tfstate   aws_instance.web aws_instance.web

# ลบ Resource ออกจาก State (Resource จริงไม่ถูกลบ)
terraform state rm aws_instance.web
# ใช้เมื่อ: ต้องการ "unmanage" Resource ให้ Terraform หยุดจัดการ

# ดู Resource ทั้งหมดใน State
terraform state list

# ดูรายละเอียดของ Resource
terraform state show aws_instance.web

# ดึง State ทั้งหมดมาดู
terraform state pull > state.json

# Push State กลับ (อันตราย ใช้ด้วยความระวัง!)
terraform state push state.json

State Encryption — ปกป้องข้อมูลลับ

State file มักมี Sensitive data เช่น Database password, API keys, Private keys ดังนั้น ต้อง Encrypt เสมอ:

Encryption at Rest

# S3 Backend — เปิด Encryption
terraform {
  backend "s3" {
    bucket     = "my-terraform-state"
    key        = "prod/terraform.tfstate"
    region     = "ap-southeast-1"
    encrypt    = true           # SSE-S3
    kms_key_id = "arn:aws:kms:ap-southeast-1:123456789:key/abc-123"  # SSE-KMS
  }
}

# Azure Backend — Encryption เปิดอัตโนมัติ
# GCS Backend — Encryption เปิดอัตโนมัติ

Sensitive Values ใน State

# ใน Terraform Code สามารถ mark variable เป็น sensitive
variable "db_password" {
  type      = string
  sensitive = true
}

output "db_connection" {
  value     = "postgres://user:${var.db_password}@${aws_db_instance.main.endpoint}"
  sensitive = true
}

# แม้ mark sensitive แล้ว ค่าจริงยังอยู่ใน State file
# sensitive = true แค่ซ่อนจาก CLI output เท่านั้น
# ดังนั้น State file ต้อง Encrypt + Access control ที่ดี

# IAM Policy สำหรับ State Bucket (ให้เข้าถึงเฉพาะคนที่จำเป็น)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::my-terraform-state/*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/Team": "infrastructure"
        }
      }
    }
  ]
}

State Backup Strategy

State file เสียหาย = หายนะ ดังนั้นต้องมี Backup strategy ที่แน่นหนา:

1. S3 Versioning (สำคัญที่สุด)

# เปิด Versioning บน S3 Bucket
aws s3api put-bucket-versioning   --bucket my-terraform-state-prod   --versioning-configuration Status=Enabled

# ดู Version เก่า
aws s3api list-object-versions   --bucket my-terraform-state-prod   --prefix prod/terraform.tfstate

# กู้คืน Version เก่า
aws s3api get-object   --bucket my-terraform-state-prod   --key prod/terraform.tfstate   --version-id "abc123"   restored-state.json

2. Cross-Region Replication

# Replicate State bucket ไปอีก Region เพื่อ Disaster Recovery
aws s3api put-bucket-replication   --bucket my-terraform-state-prod   --replication-configuration '{
    "Role": "arn:aws:iam::123456789:role/s3-replication",
    "Rules": [{
      "Status": "Enabled",
      "Destination": {
        "Bucket": "arn:aws:s3:::my-terraform-state-dr"
      }
    }]
  }'

3. Pre-apply Backup Script

#!/bin/bash
# backup-state.sh — รันก่อนทุก apply
BUCKET="my-terraform-state-prod"
KEY="prod/terraform.tfstate"
BACKUP_DIR="./state-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR
aws s3 cp "s3://$BUCKET/$KEY" "$BACKUP_DIR/tfstate_$TIMESTAMP.json"
echo "State backed up: $BACKUP_DIR/tfstate_$TIMESTAMP.json"

# ลบ Backup เก่ากว่า 90 วัน
find $BACKUP_DIR -name "tfstate_*.json" -mtime +90 -delete

Terraform Cloud State Management

Terraform Cloud (หรือ Terraform Enterprise) ให้ State Management ที่ครบครัน รวม Remote execution, Policy as Code (Sentinel), VCS integration:

# backend.tf สำหรับ Terraform Cloud
terraform {
  cloud {
    organization = "my-company"
    workspaces {
      name = "prod-infrastructure"
    }
  }
}

# Terraform Cloud ให้:
# - Remote State Storage + Encryption
# - State Locking อัตโนมัติ
# - State Version History พร้อม Diff
# - Access Control (Team-based)
# - Run history + Audit log
# - Policy as Code (Sentinel / OPA)
# - Cost Estimation
# - Private Registry สำหรับ Modules

# terraform login
# terraform init

Common State Problems and Fixes

1. State Drift — State ไม่ตรงกับ Reality

# ปัญหา: มีคนไปแก้ Resource ด้วยมือ (Console/CLI)
# ทำให้ State ไม่ตรงกับ Resource จริง

# แก้ไข: Refresh State
terraform refresh          # Deprecated ใน Terraform 1.5+
terraform apply -refresh-only  # วิธีใหม่

# Terraform จะ Query Cloud จริง แล้วอัปเดต State ให้ตรง
# แต่ไม่เปลี่ยน Configuration (.tf files)

# ป้องกัน: ห้ามแก้ Resource ด้วยมือ ใช้ Terraform เท่านั้น!

2. State Lock Stuck

# ปัญหา: CI/CD Pipeline ค้าง ไม่ปลด Lock
# แก้ไข:
terraform force-unlock LOCK_ID

# ตรวจสอบ DynamoDB ว่ามี Lock item ค้างไหม
aws dynamodb scan --table-name terraform-state-lock

3. State File Corrupted

# ปัญหา: State file เสียหาย อ่านไม่ได้
# แก้ไข: กู้คืนจาก S3 Version
aws s3api list-object-versions   --bucket my-terraform-state-prod   --prefix prod/terraform.tfstate   --max-items 5

# Download version ล่าสุดที่ใช้ได้
aws s3api get-object   --bucket my-terraform-state-prod   --key prod/terraform.tfstate   --version-id "GOOD_VERSION_ID"   recovered.tfstate

# Push State กลับ
terraform state push recovered.tfstate

4. Resource ใน State แต่ไม่มีใน Code

# ปัญหา: ลบ Resource block จาก .tf แล้ว terraform plan บอกจะ Destroy
# ถ้าไม่ต้องการ Destroy ให้ rm ออกจาก State ก่อน
terraform state rm aws_instance.old_server

# แล้วค่อยลบจาก .tf file

5. ย้าย Resource ข้าม Module โดยไม่ Destroy/Create

# ปัญหา: ย้าย Resource เข้า Module แล้ว Terraform จะ Destroy + Create ใหม่
# แก้ไข: ใช้ moved block (Terraform 1.1+)
moved {
  from = aws_instance.web
  to   = module.web.aws_instance.main
}

# หรือใช้ state mv
terraform state mv aws_instance.web module.web.aws_instance.main

Best Practices สำหรับ Terraform State Management

ข้อ Best Practice เหตุผล
1 ใช้ Remote State เสมอ ทำงานเป็นทีมได้ มี Locking + Versioning
2 เปิด Versioning บน State Storage กู้คืน State เก่าได้เมื่อมีปัญหา
3 เปิด Encryption State มี Sensitive data
4 ใช้ State Locking ป้องกัน Concurrent modification
5 แยก State ตาม Environment Apply dev ไม่กระทบ prod
6 แยก State ตาม Service/Layer ลด Blast radius + เร็วขึ้น
7 อย่า Commit State เข้า Git มี Sensitive data ห้ามอยู่ใน VCS
8 ใช้ -refresh-only ก่อน apply ถ้าสงสัย Drift ตรวจสอบว่า State ตรงกับ Reality
9 จำกัด Access ด้วย IAM ไม่ใช่ทุกคนควรแก้ State ได้
10 ทำ CI/CD สำหรับ Terraform ลด Human error ตรวจสอบก่อน Apply

.gitignore สำหรับ Terraform

# .gitignore
*.tfstate
*.tfstate.*
*.tfstate.backup
.terraform/
.terraform.lock.hcl
crash.log
*.tfvars   # อาจมี Sensitive values
override.tf
override.tf.json

สรุป — Terraform State Management 2026

Terraform State เป็นหัวใจสำคัญของ Infrastructure as Code ถ้าจัดการ State ไม่ดี ไม่ว่า Code จะเขียนดีแค่ไหนก็ยังเสี่ยงต่อปัญหา ใช้ Remote State (S3+DynamoDB สำหรับ AWS, Azure Blob สำหรับ Azure, GCS สำหรับ GCP) เปิด Encryption + Versioning + Locking เสมอ แยก State ตาม Environment และ Service เพื่อลด Blast radius และทำ CI/CD pipeline สำหรับ Terraform เพื่อลด Human error

เริ่มต้นวันนี้ด้วยการ Migrate Local State ไป Remote State แล้วคุณจะเข้าใจว่าทำไมการจัดการ State อย่างถูกต้อง ถึงเป็นทักษะที่ทุกทีม DevOps ต้องมีในปี 2026

.

.
.
.

จัดส่งรวดเร็วส่งด่วนทั่วประเทศ
รับประกันสินค้าเคลมง่าย มีใบรับประกัน
ผ่อนชำระได้บัตรเครดิต 0% สูงสุด 10 เดือน
สะสมแต้ม รับส่วนลดส่วนลดและคะแนนสะสม

© 2026 SiamLancard — จำหน่ายการ์ดแลน อุปกรณ์ Server และเครื่องพิมพ์ใบเสร็จ

SiamLancard
Logo
Free Forex EA — XM Signal · SiamCafe Blog · SiamLancard · Siam2R · iCafeFX
iCafeForex.com - สอนเทรด Forex | SiamCafe.net
Shopping cart