Skip to main content

Advanced State Commands

Commands ที่ใช้ใน edge cases — state pull/push, state replace-provider, force-unlock

terraform state pull

Download state file ปัจจุบัน:

terraform state pull > state.json

Use Cases

1. Backup ก่อน Risky Operation

terraform state pull > backup-$(date +%Y%m%d-%H%M%S).tfstate

2. Inspect State JSON

terraform state pull | jq '.resources[].type' | sort -u
# → list ของ resource types ทั้งหมด

3. Migrate State Format

terraform state pull > state.json
# Manual edit if needed
terraform state push state.json

terraform state push

Upload state file (overwrite remote):

terraform state push state.json
ใช้ระวัง
  • ❌ Push state ที่ผิด = corrupt state
  • ✅ Backup ก่อน push เสมอ
  • ✅ Verify ด้วย terraform plan หลัง push

Workflow: Manual State Edit

# 1. Backup
terraform state pull > backup.tfstate

# 2. Pull current
terraform state pull > current.tfstate

# 3. Edit (ระวัง! ใช้ jq หรือ tool เฉพาะ)
jq '.serial += 1' current.tfstate > new.tfstate
# (or other manual edits)

# 4. Push
terraform state push new.tfstate

# 5. Verify
terraform plan

terraform state replace-provider

เปลี่ยน provider source ใน state:

terraform state replace-provider \
registry.terraform.io/-/aws \
registry.terraform.io/hashicorp/aws

Use Cases

1. Provider Migration

# จาก legacy provider → official provider
terraform state replace-provider \
registry.terraform.io/community/aws \
registry.terraform.io/hashicorp/aws

2. Switch from Terraform → OpenTofu

terraform state replace-provider \
registry.terraform.io/hashicorp/aws \
registry.opentofu.org/hashicorp/aws

3. Internal Mirror

terraform state replace-provider \
registry.terraform.io/hashicorp/aws \
artifactory.company.internal/terraform/hashicorp/aws

ใช้ตอน: company มี internal terraform mirror

terraform force-unlock

ปลด lock ที่ค้าง:

terraform force-unlock <LOCK_ID>

LOCK_ID หาจาก error message:

Lock Info:
ID: abc123-def456

When to Force Unlock

✅ ใช้ได้:

  • Process ที่ run apply ถูก kill
  • Network disconnect ระหว่าง apply
  • Container ถูก SIGKILL

❌ อย่าใช้ถ้า:

  • ไม่แน่ใจว่ามีคนกำลัง apply อยู่
  • เพราะอยากให้ apply ของตัวเองรันได้
# ปลด lock โดย confirm
terraform force-unlock abc123-def456

# Force ไม่ confirm
terraform force-unlock -force abc123-def456
ผลของ force-unlock ผิดเวลา
  • 2 process apply พร้อมกัน → state corrupt
  • อาจสูญเสีย change ของคนหนึ่ง
  • บางครั้งแก้ไม่ได้ — ต้อง restore from backup

terraform state rm (recap)

terraform state rm aws_instance.legacy
terraform state rm 'module.old.*' # bulk

ดูใน Modify State

terraform state mv (recap)

terraform state mv aws_instance.old aws_instance.new
terraform state mv aws_vpc.main module.network.aws_vpc.main

ตัวอย่าง: Recovery Scenarios

Scenario 1: State File Corruption

# 1. Don't panic
# 2. Try downloading from backup
aws s3api list-object-versions --bucket my-tfstate --prefix prod/

# 3. Restore version
aws s3api get-object \
--bucket my-tfstate \
--key prod/terraform.tfstate \
--version-id abc123 \
recovered.tfstate

# 4. Push as current
terraform state push recovered.tfstate

# 5. Verify
terraform plan

Scenario 2: Provider Renamed

ตัวอย่าง: provider ย้ายจาก terraform-providers/awshashicorp/aws

terraform state replace-provider \
registry.terraform.io/-/aws \
registry.terraform.io/hashicorp/aws

# Verify
terraform plan
# → No changes (provider แค่ rename, resources เหมือนเดิม)

Scenario 3: Lock Stuck

$ terraform plan
Error: Error acquiring the state lock
Lock Info:
ID: abc123
Operation: OperationTypeApply
Who: alice@laptop
Created: 2026-05-07 09:00:00

# (Now is 11:00 — lock 2 hours ago, alice's machine probably crashed)

# Verify with team — alice is offline?
# Yes — safe to unlock
terraform force-unlock abc123

Scenario 4: Wrong State Pushed

# Realized I pushed wrong state file
# 1. Pull current bad state
terraform state pull > bad.tfstate

# 2. Restore previous version from S3
aws s3api list-object-versions --bucket my-tfstate
aws s3api get-object \
--bucket my-tfstate \
--key prod/terraform.tfstate \
--version-id good-version-id \
good.tfstate

# 3. Push good state
terraform state push good.tfstate

# 4. Verify
terraform plan

State File Internals

terraform.tfstate
{
"version": 4, # Format version
"terraform_version": "1.9.8",
"serial": 23, # Apply count
"lineage": "abc-123-def", # State ID — เปลี่ยนไม่ได้
"outputs": {...},
"resources": [
{
"mode": "managed", # หรือ "data"
"type": "aws_s3_bucket",
"name": "data",
"provider": "...",
"instances": [
{
"schema_version": 0,
"attributes": {...},
"dependencies": [...]
}
]
}
]
}

serial vs lineage

  • serial — เพิ่มทุก apply (1, 2, 3, ...)
  • lineage — UUID ที่ unique ต่อ state — ไม่เปลี่ยน

ถ้า push state ที่ lineage ต่าง → Terraform reject:

Error: state lineage doesn't match

→ ป้องกันการ push ผิด state

Force ผ่านกับ flag:

terraform state push -lineage=$(jq -r .lineage current.tfstate) state.tfstate

State Pull/Push as Backup Strategy

scripts/state-snapshot.sh
#!/bin/bash
set -euo pipefail

ENV=${1:?env required}
LAYER=${2:?layer required}

DATE=$(date +%Y%m%d-%H%M%S)
SNAPSHOT_DIR="snapshots/${ENV}/${LAYER}"
mkdir -p "$SNAPSHOT_DIR"

cd "${ENV}/${LAYER}"

terraform state pull > "../../${SNAPSHOT_DIR}/${DATE}.tfstate"

echo "Snapshot saved: ${SNAPSHOT_DIR}/${DATE}.tfstate"
./scripts/state-snapshot.sh prod network

Best Practices

✅ DO:
- Backup ก่อน state ops เสมอ
- Verify ด้วย terraform plan หลัง modify
- Document การเปลี่ยน state ใน commit/PR
- Coordinate force-unlock กับทีม

❌ DON'T:
- ห้าม push state ที่ edit manual โดยไม่ verify
- ห้าม force-unlock โดยไม่ confirm กับทีม
- ห้าม mix state จาก env ต่างๆ
- ห้าม skip backup เพราะ "เร็ว"

สรุป

Commandหน้าที่
state pullDownload state
state pushUpload state (overwrite)
state replace-providerChange provider source
force-unlockRelease stuck lock
state mvRename / relocate
state rmRemove from state (no destroy)
apply -replaceForce destroy + recreate

State commands = สำคัญเวลาแก้ไขปัญหา — แต่ใช้ระวัง: backup + verify เสมอ

ต่อไป → Section 12: Modules