Terraform làm gì trong mỗi vòng đời?
Mỗi lần chạy plan, Terraform so sánh ba thứ: code cấu hình, state và dữ liệu thực tế từ provider. Từ đó nó chọn hành động:
+tạo mới;~cập nhật tại chỗ;-/+hủy rồi tạo lại (replace);-xóa;- không có thay đổi là
no-op.
Ví dụ với bucket S3:
resource "aws_s3_bucket" "logs" {
bucket = "my-company-dev-logs-12345"
tags = { Environment = "dev" }
}
Lần đầu terraform plan sẽ đề xuất tạo. Sau apply, chạy plan lần nữa thường là no-op. Nếu đổi tag, Terraform cập nhật metadata; nếu đổi một thuộc tính “ForceNew”, nó phải replace resource.
Dùng lifecycle để nói rõ ý định
resource "aws_s3_bucket" "production" {
bucket = "my-company-production-logs"
lifecycle {
prevent_destroy = true
}
}
prevent_destroy là một lan can an toàn, không phải backup. Khi cần xóa có chủ đích, phải bỏ cấu hình này rồi plan lại trong một change đã review.
Với resource có tên/ID thay đổi, có thể giảm khoảng trống bằng:
lifecycle {
create_before_destroy = true
}
Không phải resource nào cũng hỗ trợ chạy song song; quota, tên duy nhất và dependency vẫn có thể khiến deployment thất bại.
ignore_changes chỉ nên dùng khi một hệ thống khác được phép sở hữu thuộc tính đó:
lifecycle {
ignore_changes = [tags["LastScannedAt"]]
}
Drift: ai đã sửa ngoài Terraform?
Giả sử ai đó đổi tag trực tiếp trên Console. Lần plan sau sẽ báo thay đổi để đưa thực tế về code. Đừng vội thêm ignore_changes cho hết cảnh báo: trước tiên cần biết thay đổi đó là hợp lệ hay là thao tác nhầm.
Quy trình xử lý an toàn:
- Chạy
terraform planvà đọc resource/thuộc tính bị lệch. - Đối chiếu audit log, Console và commit gần nhất.
- Nếu code mới là nguồn sự thật, apply để sửa drift.
- Nếu thay đổi tay là đúng, cập nhật code rồi plan lại.
terraform plan -refresh-only
Lệnh này chỉ cập nhật state theo remote và giúp quan sát drift; nó không nên được dùng để “che” một thay đổi chưa được review.
Lab mô phỏng drift
Với bucket test, thêm tag Owner = "terraform" bằng Console rồi chạy:
terraform plan
Nếu tag đó được quản lý trong code, plan sẽ đề xuất đưa nó về giá trị trong code. Nếu team có quy ước cho phép một hệ thống khác cập nhật tag, hãy mô tả ownership đó bằng ignore_changes thật cụ thể và ghi lý do trong comment. Đừng ignore cả tags chỉ để plan xanh; như vậy ta mất tín hiệu audit.
Chọn create_before_destroy hay replace?
Hãy xem resource có tên duy nhất, quota và dependency hay không. Với database, replace thường là rủi ro dữ liệu; với launch template, tạo bản mới trước thường hợp lý. Lifecycle là quyết định kiến trúc, không phải công tắc “giảm downtime” áp dụng cho mọi resource.
Xem thêm bài nguồn về resource lifecycle. Hãy thử bài này với một bucket test và nhớ dọn tài nguyên sau lab.