TL;DR
Chạy một trong các lệnh sau tùy thuộc vào những gì bạn đã thay đổi:
# Bucket hoặc đường dẫn key thay đổi? Di chuyển state.
terraform init -migrate-state
# Chỉ credentials hoặc cài đặt nhỏ thay đổi? Chỉ cần cập nhật config.
terraform init -reconfigure
Chọn -migrate-state khi bucket hoặc đường dẫn thay đổi. Chọn -reconfigure khi chỉ credentials hoặc các cài đặt không quan trọng thay đổi và state đã ở đúng vị trí.
Nguyên Nhân Gây Ra Lỗi
Terraform lưu trữ một hash của cấu hình backend bên trong .terraform/terraform.tfstate. Mỗi lần chạy terraform init, nó so sánh nội dung trong các file *.tf với hash đã cache. Nếu không khớp, Terraform dừng lại — không tự động tiếp tục. Đây là chủ ý. Vô tình trỏ vào sai bucket state có thể gây ra thảm họa, nên Terraform buộc bạn phải xác nhận thay đổi một cách rõ ràng.
Các tình huống thường gặp kích hoạt lỗi này:
- Thay đổi tên bucket S3 hoặc GCS
- Thay đổi
key(đường dẫn) bên trong bucket - Chuyển đổi AWS region cho S3 backend
- Đổi tên hoặc chuyển workspace ảnh hưởng đến đường dẫn backend
- Pull code của người khác mà cấu hình backend khác với cache cục bộ của bạn
- Chuyển từ local backend sang S3/GCS (hoặc ngược lại)
Cách 1: Di Chuyển State Sang Backend Mới
Đã thay đổi nơi lưu trữ state? Đây là lệnh bạn cần:
terraform init -migrate-state
Đây là những gì diễn ra bên dưới:
- Terraform kết nối với backend cũ và đọc state hiện có
- Nó ghi state đó vào vị trí backend mới
- Nó yêu cầu xác nhận trước khi thực hiện bất kỳ thao tác nào
Prompt trông như thế này:
Initializing the backend...
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "s3" backend to the
newly configured "s3" backend. No existing state was found in the newly
configured "s3" backend. Do you want to copy this state to the new backend?
Enter a value: yes
Nhập yes và Terraform sẽ xử lý phần còn lại.
Cách 2: Reconfigure Mà Không Di Chuyển State
Đôi khi cấu hình backend thay đổi, nhưng bản thân state đã ở đúng vị trí. Có thể bạn đã xoay vòng credentials, cập nhật tên profile AWS CLI, hoặc chỉnh sửa một tham số không liên quan đến nơi lưu state. Trong trường hợp đó:
terraform init -reconfigure
Lệnh này cập nhật hash cache cục bộ mà không động đến state. Nhanh và không gây mất dữ liệu.
Cảnh báo: Đừng dùng -reconfigure nếu bạn thực sự đã thay đổi tên bucket hoặc đường dẫn key. State sẽ trỏ đến vị trí sai và plan hoặc apply sẽ cho ra kết quả khó hiểu — thậm chí nguy hiểm.
Tình Huống Phổ Biến: Chuyển Đổi Bucket hoặc Key S3
Trước (config cũ):
terraform {
backend "s3" {
bucket = "my-tf-state-old"
key = "prod/terraform.tfstate"
region = "us-east-1"
}
}
Sau (config mới):
terraform {
backend "s3" {
bucket = "my-tf-state-new"
key = "prod/terraform.tfstate"
region = "us-east-1"
}
}
Chạy:
terraform init -migrate-state
Trước khi làm — hãy xác nhận bạn có quyền đọc bucket cũ và quyền ghi bucket mới. Thiếu một trong hai quyền sẽ khiến quá trình migration thất bại giữa chừng.
Tình Huống Phổ Biến: Thay Đổi GCS Backend
terraform {
backend "gcs" {
bucket = "my-project-tf-state"
prefix = "terraform/state"
}
}
Đã thay đổi bucket hoặc prefix? Cách khắc phục tương tự:
terraform init -migrate-state
Migration GCS theo cùng một quy trình — Terraform đọc từ vị trí GCS cũ, ghi vào vị trí mới. Không cần thêm bước nào.
Trường Hợp Đặc Biệt: Cấu Hình Backend Trong Partial Config Files
Một số team không hardcode giá trị backend mà truyền vào lúc init:
terraform init \
-backend-config="bucket=my-tf-state" \
-backend-config="key=prod/terraform.tfstate" \
-backend-config="region=us-east-1"
Hoặc qua file backend.hcl:
# backend.hcl
bucket = "my-tf-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
terraform init -backend-config=backend.hcl
Nếu file đó thay đổi, bạn sẽ gặp cùng lỗi. Cách sửa: thêm -migrate-state hoặc -reconfigure vào cùng lệnh:
terraform init -backend-config=backend.hcl -migrate-state
Xác Minh Sau Khi Sửa
Sau khi init hoàn tất, hai kiểm tra nhanh sẽ cho bạn biết migration có thực sự thành công không:
# Nên trả về các resource bạn mong đợi
terraform state list
# Nên không hiển thị thay đổi bất ngờ
terraform plan
Nếu state list trả về các resource của bạn, mọi thứ ổn. Nếu không trả về gì trong khi bạn mong đợi hàng chục resource, state chưa được migrate — kiểm tra quyền IAM trên bucket và chạy lại terraform init -migrate-state.
Mẹo Phòng Tránh
Các thay đổi backend gây ra nhiều rắc rối nhất khi chúng xảy ra âm thầm giữa sprint. Một vài thói quen sẽ giảm đáng kể rủi ro đó:
- Commit
backend.hclhoặc backend block cùng với bất kỳ thay đổi infrastructure nào. Đừng thay đổi cấu hình backend một mình mà không thông báo cho team trước. - Đảm bảo
.terraform/nằm trong.gitignore— thường đã có, nhưng hãy kiểm tra lại. Commit hash backend đã cache sẽ làm hỏng môi trường của mọi đồng nghiệp pull code của bạn. - Trước khi động vào backend, hãy snapshot state:
terraform state pull > backup-$(date +%Y%m%d).tfstate. Mất 2 giây, tiết kiệm hàng giờ nếu có sự cố. - Nếu cấu hình backend của bạn nằm trong biến CI dạng YAML, YAML ↔ JSON Converter trên ToolCraft rất tiện để validate cấu trúc config trước khi đưa vào pipeline — chạy hoàn toàn trên trình duyệt, không có dữ liệu nào rời khỏi máy bạn.
Sơ Đồ Quyết Định Nhanh
- Đã thay đổi tên bucket hoặc đường dẫn key? →
terraform init -migrate-state - Chỉ thay đổi credentials, profile, hoặc cài đặt nhỏ? →
terraform init -reconfigure - Pull code của người khác và cache cục bộ đã cũ? →
terraform init -reconfigure(giả sử remote backend không thay đổi) - Chuyển từ local backend sang remote lần đầu tiên? →
terraform init -migrate-stateđể upload file state cục bộ lên remote backend

