Terraform State Backup & Recovery: แผนกู้คืนเมื่อ State เสียหาย

แม้ remote backend จะมี versioning และ locking แต่อุบัติเหตุยังเกิดได้เสมอ เช่น state rm ผิด resource, migration ล้มเหลวกลางทาง, หรือ bucket ถูกลบโดยไม่ตั้งใจ การมีแผน backup และ recovery ที่ชัดเจนจึงเป็นเรื่องจำเป็น ไม่ใช่ของหรูหรา

บทความนี้จะครอบคลุม 3 ประเด็น: วิธี backup state อย่างสม่ำเสมอ, การ restore จาก version เก่าบน S3, และการ rebuild state จากศูนย์ด้วย terraform import เมื่อไฟล์หายไปจริง ๆ

กลยุทธ์ Backup 3 ชั้น

  • Automatic backup จาก backend — S3 versioning, Azure blob soft-delete, Cloud edition state history
  • Manual backup ก่อน operation เสี่ยงstate rm, state mv, backend migration
  • Scheduled snapshot ไปที่ secondary location — copy state ไปอีก bucket/region เพื่อรองรับ disaster

Manual Backup ก่อน Operation เสี่ยง

# ดึง state ปัจจุบันจาก remote มาเก็บไว้ local
terraform state pull > backup-$(date +%Y%m%d-%H%M%S).tfstate

# หรือ copy ตรงจาก S3
aws s3 cp \
  s3://mycompany-tfstate/prod/network/terraform.tfstate \
  ./backup-prod-network-$(date +%Y%m%d).tfstate

# ตรวจว่า backup ครบ
jq '.resources | length' backup-prod-network-20260415.tfstate

การ pull state ลงมาเป็นไฟล์ local ก่อนเสมอก่อนรัน state rm หรือ state mv เป็นวินัยที่ช่วยหลายครั้ง เพราะถ้าทำพลาด ยังสามารถ push state กลับขึ้นไปได้

Restore จาก S3 Version

ถ้าเปิด versioning บน S3 (ตามที่แนะนำในบทความก่อนหน้า) สามารถ restore version ก่อนหน้าได้ตรง ๆ

# 1. ดูรายการ version ทั้งหมด
aws s3api list-object-versions \
  --bucket mycompany-tfstate \
  --prefix prod/network/terraform.tfstate \
  --query 'Versions[*].[VersionId,LastModified,IsLatest]' \
  --output table

# 2. ดาวน์โหลด version เก่าที่ต้องการ
aws s3api get-object \
  --bucket mycompany-tfstate \
  --key prod/network/terraform.tfstate \
  --version-id "abc123xyz789" \
  restored.tfstate

# 3. push กลับขึ้น remote (หลังตรวจแล้ว)
terraform state push restored.tfstate

ก่อน push ต้องตรวจ serial number ในไฟล์ — ถ้าน้อยกว่า state ปัจจุบัน tool จะปฏิเสธเพราะคิดว่าเป็นไฟล์เก่ากว่า ใช้ flag -force ถ้ายืนยันว่าต้องการ (อันตราย ใช้เมื่อมั่นใจเท่านั้น)

Scheduled Snapshot ไปยัง Secondary

สำหรับ state สำคัญควรมี cross-region backup กรณี bucket ต้นฉบับเสียหาย หรือ credential ถูก compromise

# S3 Replication Rule (Terraform configuration)
resource "aws_s3_bucket_replication_configuration" "tfstate" {
  role   = aws_iam_role.replication.arn
  bucket = aws_s3_bucket.tfstate.id

  rule {
    id     = "replicate-to-dr"
    status = "Enabled"

    destination {
      bucket        = "arn:aws:s3:::mycompany-tfstate-dr"
      storage_class = "STANDARD_IA"
      encryption_configuration {
        replica_kms_key_id = aws_kms_key.dr.arn
      }
    }
  }
}

Rebuild State ด้วย terraform import

กรณีเลวร้ายที่สุดคือ state หายไปจริง ๆ ไม่มี version ให้ restore ทางออกคือ import resource ทีละตัวเข้ามาใน state ใหม่ โดยที่ config เดิมยังอยู่

# 1. เตรียม config ให้ตรงกับ resource ที่มีอยู่จริง
resource "aws_instance" "web" {
  ami           = "ami-0abc1234"
  instance_type = "t3.small"
  # ... attribute อื่น ๆ
}

# 2. import ทีละ resource
$ terraform import aws_instance.web i-0123456789abcdef0

# 3. รัน plan เพื่อตรวจว่า config ตรงกับ state ใหม่
$ terraform plan
# ควรเห็น "No changes. Your infrastructure matches the configuration."

วิธีนี้เหนื่อยและใช้เวลานาน ยิ่งมี resource มากยิ่งใช้เวลา มีเครื่องมือ third-party เช่น terraformer หรือ aws2tf ที่ช่วยสแกน resource ใน cloud แล้ว generate config + import script อัตโนมัติ เหมาะสำหรับ disaster recovery หรือ onboard infrastructure legacy เข้ามา

ข้อควรระวัง

  • Backup ไฟล์ local มี secret ต้องเก็บใน encrypted volume และลบเมื่อใช้เสร็จ — อย่า commit Git
  • ก่อน state push -force ต้องตรวจ diff อย่างละเอียด เพราะอาจทับ resource ใหม่ที่ apply ระหว่างนั้น
  • Import config ต้องตรง attribute กับของจริงในคราวเดียว ถ้าไม่ตรงจะ plan แสดง changes ที่ไม่ต้องการ
  • อย่าพยายาม merge state file ด้วย text editor — ใช้ state pull/push หรือคำสั่ง state เท่านั้น
  • ตั้ง alert บน S3 lifecycle/deletion event เพื่อตรวจจับการลบ state โดยไม่ตั้งใจ

Recovery Drill

หลังมี backup plan แล้ว ควรฝึกซ้อม recovery อย่างน้อยปีละครั้ง บน environment ทดสอบ เพื่อให้ทีมคุ้นเคยขั้นตอนจริง เช่นลอง state rm resource หนึ่งแล้ว restore กลับจาก version ก่อน หรือ import resource ใหม่ที่ไม่มีใน state การซ้อมนี้ช่วยให้เจอปัญหา IAM, permission, หรือ runbook ที่ไม่อัพเดตก่อนเกิดเหตุจริง

สรุป

State file เป็น asset ที่หายแล้วกู้คืนยาก การวางแผน backup 3 ชั้น (versioning, manual, cross-region replication) และฝึกซ้อม recovery เป็นสิ่งที่ทุกทีม infrastructure ควรทำ กรณีเลวร้ายสุดยังสามารถ rebuild state ด้วย terraform import แต่ใช้เวลาและแรงงานมาก — จึงควรป้องกันไม่ให้ถึงจุดนั้น ในบทความถัดไปจะเริ่มพูดถึง built-in functions ที่ใช้ในการเขียน HCL ซึ่งเป็นเครื่องมือสำคัญในการสร้าง configuration ที่ยืดหยุ่น