Terraform
← Tổng quan series

Khi Terraform state lệch infrastructure thật

Điều tra drift, dùng refresh-only, import block và state command để đưa resource có sẵn về đúng mô hình quản lý.

Instructor walkthrough

Bài giảng: hiểu luồng trước khi chạy lệnh

Bài toán: Điều tra drift, dùng refresh-only, import block và state command để đưa resource có sẵn về đúng mô hình quản lý.

01Chuẩn bịkiểm tra account, region, provider và chi phí
02Đọc planđối chiếu resource address, diff và dependency
03Thực hànhapply mutation nhỏ trong sandbox, lưu evidence
04Khôi phụcre-run, failure drill, destroy hoặc rollback
Command reference · baseline
terraform fmt
terraform init
terraform validate
terraform plan
terraform apply
terraform plan -destroy
terraform destroy

Ba trạng thái có thể khác nhau

Terraform không chỉ so code với state. Provider refresh state từ infrastructure thật rồi mới lập plan. Vì thế lỗi có thể đến từ:

  1. Resource tồn tại thật nhưng không có trong state.
  2. State còn ghi resource nhưng nó đã bị xóa ngoài cloud.
  3. Resource tồn tại, nhưng thuộc tính/tag/config bị sửa ngoài Terraform.

Quan sát trước, sửa sau

terraform state list
terraform state show aws_instance.app
terraform plan

Muốn cập nhật state theo remote mà chưa sửa infrastructure:

terraform plan -refresh-only
terraform apply -refresh-only

Hãy review output như một thay đổi production. Refresh-only không “sửa drift”; nó làm Terraform ghi nhận hiện trạng mới vào state, sau đó plan bình thường có thể đề xuất đưa code về trạng thái mong muốn.

Import resource có sẵn

Nếu một bucket đã được tạo tay, viết resource block trước rồi dùng import block:

resource "aws_s3_bucket" "existing" {
  bucket = "company-existing-assets"
}

import {
  to = aws_s3_bucket.existing
  id = "company-existing-assets"
}
terraform plan

Sau khi import, plan có thể còn nhiều thay đổi vì code chưa mô tả hết cấu hình thật. Thêm dần các thuộc tính cần quản lý và xác nhận từng lần. Không import một resource production vào code sơ sài rồi apply ngay.

Resource đã bị xóa ngoài cloud

Nếu state vẫn có resource nhưng provider báo không tìm thấy, Terraform thường đề xuất tạo lại. Kiểm tra xem việc tạo lại có ảnh hưởng dữ liệu hay dependency không. Với resource đã chuyển quyền quản lý sang hệ thống khác, có thể dùng terraform state rm để bỏ khỏi state, nhưng lệnh này không xóa resource ngoài cloud và phải có approval:

terraform state rm aws_s3_bucket.legacy

Quy trình recovery

  1. Khóa thay đổi đồng thời.
  2. Backup/kiểm tra version state.
  3. Đọc audit log để biết thay đổi ngoài Terraform.
  4. Chọn import, sửa code, refresh-only hoặc state rm.
  5. Chạy plan và review dependency/destroy.
  6. Apply một thay đổi nhỏ, rồi kiểm tra lại plan.

Khi nào dùng moved block?

Nếu chỉ đổi địa chỉ trong code, ví dụ đưa resource vào module, không nên để Terraform hiểu đó là xóa và tạo lại:

moved {
  from = aws_s3_bucket.assets
  to   = module.storage.aws_s3_bucket.this
}

Chạy plan để xác nhận Terraform ghi nhận move, không có destroy/create. Giữ moved block đủ lâu cho mọi branch/workspace đã nâng cấp; sau đó có thể dọn theo chính sách của team. Đây là cách an toàn hơn so với sửa state thủ công.

Bài tập recovery không phá dữ liệu

Tạo một bucket test, import vào state, thêm một tag ngoài Console, chạy plan để thấy drift, rồi cập nhật code cho khớp. Cuối cùng chạy terraform plan -refresh-only và xác nhận no-op. Không thực hành state rm, import hoặc refresh trên production nếu chưa có backup và người thứ hai review.

Expected state và recovery decision table

Tạo resource test có tag/owner, backup state trước mutation và khóa operation. Expected state của từng scenario:

Tình huống Evidence trước sửa Hành động phù hợp Gate sau sửa
Drift ngoài code plan/audit/remote attributes sửa code hoặc apply code có review plan no-op, owner xác nhận
Resource có thật, thiếu state provider lookup/import plan resource block + import import không tạo/xóa ngoài ý muốn
State còn, remote đã mất provider not-found/dependency đánh giá recreate hoặc remove state data/owner/plan destroy review
Chỉ đổi địa chỉ code plan address diff moved block không destroy/create

Thực hiện drill import/refresh/moved trên sandbox, lưu state backup/version, plan artifact và timeline. Cố ý sai ID/provider alias/module address để thấy failure; không sửa state JSON bằng tay, không chạy state rm để che plan và không apply recreate resource chứa data nếu chưa có backup/approval. Sau mỗi remediation chạy plan bình thường và kiểm tra resource thật, dependency, outputs và no-op.

Quality gate

Pass khi người học chọn đúng import, refresh-only, sửa code, recreate, state rm hoặc moved theo evidence; phân biệt state update với infrastructure remediation; giữ lock/backup/audit/owner; chứng minh không có destroy/create ngoài ý muốn và cleanup chỉ resource lab. state rm không xóa resource thật hay lịch sử state cũ.