SRE RunbookMÃ: 010-TERRAFORM-IAC-RUNBOOK⏱️ Đọc ~5 phút

Terraform IaC Runbook: Xử Lý Sự Cố State Lock, Phát Hiện Drift Và Refactor Hạ Tầng Không Sập Production

Terraform là công cụ Infrastructure as Code (IaC) tiêu chuẩn của ngành công nghệ đám mây. Nhưng bất kỳ ai quản trị Terraform trên môi trường thực tế đều từng trải qua cảm giác...

Khổ: 1080×1350 (4:5)Tối ưu Mobile & In ấn

Terraform IaC Runbook: Xử Lý Sự Cố State Lock, Phát Hiện Drift Và Refactor Hạ Tầng Không Sập Production

Terraform là công cụ Infrastructure as Code (IaC) tiêu chuẩn của ngành công nghệ đám mây. Nhưng bất kỳ ai quản trị Terraform trên môi trường thực tế đều từng trải qua cảm giác thót tim: một pipeline CI/CD rớt mạng giữ chặt State Lock, một đồng nghiệp sửa tay trên AWS Console gây lệch chuẩn (State Drift), hay việc đổi tên một module khiến Terraform đòi xoá sạch cơ sở dữ liệu production.

Bài viết này tổng hợp toàn bộ các kỹ thuật thực chiến và câu lệnh cứu hộ chuẩn SRE để làm chủ Terraform State và tự tin refactor hạ tầng.


1. Xử lý State Lock khi CI/CD Crash

Triệu chứng

Khi chạy terraform plan hoặc terraform apply, bạn nhận được thông báo lỗi:

Error: Error acquiring the state lock
Lock Info:
  ID:        b7d5f0e1-4c2a-9e8f-7b1a-2c3d4e5f6a7b
  Path:      my-org-tfstate/prod/terraform.tfstate
  Operation: OperationTypeApply
  Who:       runner@github-actions-01
  Created:   2026-10-21 07:30:00.000000 UTC

Nguyên nhân

Khi dùng remote backend (như AWS S3 + DynamoDB, Terraform Cloud, hay GitLab HTTP backend), Terraform tạo một lock entry trước khi thực thi để ngăn ngừa race condition từ hai kỹ sư cùng apply một lúc. Nếu container runner bị OOM, bị huỷ bởi timeout hoặc rớt mạng giữa chừng, transaction không thể dọn dẹp lock.

Cách xử lý an toàn

  1. Kiểm tra trạng thái runner: Đảm bảo pipeline trước đó thực sự đã chết, không còn tác vụ ngầm nào đang ghi vào state.
  2. Giải phóng lock:
terraform force-unlock b7d5f0e1-4c2a-9e8f-7b1a-2c3d4e5f6a7b
  1. Sao lưu state trước khi chạy tiếp:
terraform state pull > tfstate-backup-$(date +%Y%m%d%H%M%S).json
  1. Đồng bộ lại tài nguyên:
terraform plan -refresh-only

2. Phát Hiện và Xử Lý State Drift (Lệch chuẩn hạ tầng)

Triệu chứng

Ai đó đã đăng nhập vào AWS/GCP Console bằng tay để mở rộng dung lượng ổ đĩa EBS hoặc thêm một rule Security Group để fix bug nóng, nhưng quên commit vào mã nguồn Terraform.

Cách phát hiện tự động

Chạy lệnh plan với cờ -detailed-exitcode:

terraform plan -detailed-exitcode

Lệnh này trả về mã thoát hệ thống:
- 0: Thành công, hạ tầng hoàn toàn khớp với state (không có diff).
- 1: Gặp lỗi cú pháp hoặc kết nối provider.
- 2: Thành công, nhưng phát hiện có sự sai lệch (Drift / Diff).

Mẹo CI/CD: Cấu hình cronjob GitHub Actions chạy terraform plan -detailed-exitcode mỗi đêm. Nếu exit code là 2, tự động gửi cảnh báo về Slack/Telegram cho team DevOps.

Cách xử lý Drift

  • Nếu thay đổi trên Cloud là đúng: Chạy terraform apply -refresh-only để cập nhật state, sau đó bổ sung thuộc tính tương ứng vào file HCL.
  • Nếu thay đổi trên Cloud là sai luật: Chạy terraform apply để ghi đè, đưa hạ tầng về đúng với định nghĩa mã nguồn.

3. Refactor Module và Đổi Tên Resource Không Bị Destroy

Vấn đề kinh điển

Khi bạn đổi tên resource trong HCL:

# Cũ
resource "aws_db_instance" "master" { ... }

# Mới
resource "aws_db_instance" "primary" { ... }

Terraform sẽ coi đây là xoá resource cũ và tạo mới resource khác! Với RDS Database hoặc S3 Bucket, điều này dẫn đến thảm hoạ mất dữ liệu.

Giải pháp 1: Dùng block moved (Khuyên dùng từ Terraform 1.1+)

Thêm block moved trực tiếp vào mã nguồn:

moved {
  from = aws_db_instance.master
  to   = aws_db_instance.primary
}

Khi chạy terraform plan, Terraform nhận diện đây là hành động đổi tên trong state (Rename in place) và không thực hiện bất kỳ lệnh xoá nào trên cloud.

Giải pháp 2: Di chuyển state thủ công (CLI)

terraform state mv aws_db_instance.master aws_db_instance.primary

4. Import Tài Nguyên Cloud Vào IaC Tự Động (Terraform 1.5+)

Trước phiên bản 1.5, kỹ sư phải tự gõ từng dòng HCL bằng tay rồi mới chạy terraform import. Giờ đây, Terraform hỗ trợ sinh mã nguồn tự động:

  1. Tạo file imports.tf:
import {
  to = aws_s3_bucket.public_assets
  id = "my-prod-public-assets-bucket"
}
  1. Chạy lệnh sinh config:
terraform plan -generate-config-out=generated_resources.tf

Terraform sẽ tự động kết nối lên Cloud, quét toàn bộ cấu hình thực tế và ghi ra file generated_resources.tf hoàn chỉnh. Bạn chỉ cần review lại và merge vào codebase!


5. Tóm Tắt 6 Quy Tắc Vàng Khi Vận Hành Terraform State

  1. Remote Backend có Lock: Luôn dùng S3 có bật Versioning kết hợp DynamoDB Locking.
  2. Backup trước khi can thiệp: Luôn chạy terraform state pull > tf.bak trước bất kỳ thao tác state rm hay state mv.
  3. Ưu tiên block moved: Khai báo declarative trong Git giúp đồng đội pull code về không bị lỗi xung đột state.
  4. Không lạm dụng -target: Chỉ dùng -target trong trường hợp cô lập lỗi khẩn cấp vì nó phá vỡ cây phụ thuộc (dependency graph).
  5. Tận dụng -replace: Thay thế cho terraform taint đã lỗi thời khi cần huỷ và tạo lại một node cụ thể.
  6. Bật TF_LOG khi gặp bế tắc: export TF_LOG=DEBUG TF_LOG_PATH=tf.log là chìa khoá để soi chi tiết từng HTTP payload gửi tới nhà cung cấp đám mây.

💡 Mẹo lưu trữ & sử dụng trong đội ngũ

Bạn có thể tải bản PDF vector về lưu trữ trong kho tài liệu nội bộ của team (Notion, Confluence) hoặc in khổ A4 dán tại bàn làm việc để tra cứu nhanh khi gặp sự cố lúc nửa đêm.