Khi bạn chạy terraform apply, Terraform cần ghi lại “thực tế đang có gì” để lần sau biết cần thay đổi gì. Thông tin đó được lưu trong state file. Backend quyết định state file đó được lưu ở đâu và quản lý như thế nào.
State file là gì – trước khi nói về backend
Sau lần terraform apply đầu tiên, bạn sẽ thấy file terraform.tfstate xuất hiện. Nội dung trông như này:
{
"version": 4,
"terraform_version": "1.5.0",
"resources": [
{
"type": "aws_instance",
"name": "example",
"instances": [
{
"attributes": {
"id": "i-0abc123def456",
"ami": "ami-12345678",
"instance_type": "t2.micro"
}
}
]
}
]
}
Terraform dùng file này để biết resource nào đang tồn tại thực tế trên cloud. Lần apply tiếp theo, nó so sánh config mới với state hiện tại để tính ra cần tạo/sửa/xóa gì.
Backend quyết định file này được lưu ở đâu.
Các loại backend
local – Mặc định, lưu trên máy
Nếu bạn không cấu hình gì, Terraform dùng local backend – lưu state ngay trong thư mục project:
project/
├── main.tf
├── variables.tf
└── terraform.tfstate ← state file nằm ở đây
Cấu hình tường minh (thường không cần viết vì đây là default):
terraform {
backend "local" {
path = "terraform.tfstate"
}
}
Phù hợp khi làm một mình, thử nghiệm, hoặc project nhỏ. Không phù hợp khi làm việc nhóm vì state nằm trên máy của từng người.
s3 – Lưu trên Amazon S3
Cách phổ biến nhất khi làm việc với AWS. State được lưu trên S3 bucket, mọi người trong team đều trỏ vào cùng một chỗ:
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "ap-southeast-1"
dynamodb_table = "terraform-lock" # dùng cho state locking
encrypt = true
}
}
key là đường dẫn của file trong bucket. Nếu bạn quản lý nhiều môi trường, đặt key khác nhau để tránh ghi đè:
prod/terraform.tfstate
staging/terraform.tfstate
dev/terraform.tfstate
consul – Lưu trên Consul
Thường dùng trong môi trường đã có HashiCorp stack (Vault, Nomad, Consul):
terraform {
backend "consul" {
address = "consul.example.com:8500"
scheme = "https"
path = "terraform/state"
}
}
Tại sao không dùng local backend cho team?
Hình dung scenario này:
Người A chạy terraform apply lúc 10:00
Người B chạy terraform apply lúc 10:01 (state file trên máy B đã cũ)
→ B không biết A vừa tạo gì
→ B apply với state cũ → conflict, duplicate resource, hoặc tệ hơn là xóa nhầm thứ A vừa tạo
Remote backend giải quyết điều này bằng 3 cơ chế:
1. Centralized state – mọi người đọc/ghi cùng một state file trên remote storage, không ai có bản riêng.
2. State locking – khi một người đang apply, backend lock state lại. Người khác chạy apply cùng lúc sẽ thấy thông báo:
Error: Error acquiring the state lock
Lock Info:
ID: abc-123
Path: prod/terraform.tfstate
Operation: OperationTypeApply
Who: user-a@machine
Created: 2024-01-15 10:00:00
Phải đợi người kia xong, hoặc force-unlock nếu có sự cố.
Với S3 backend, state locking dùng DynamoDB. Bảng DynamoDB cần có primary key là LockID:
resource "aws_dynamodb_table" "terraform_lock" {
name = "terraform-lock"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
3. Backup tự động – S3 có versioning, mỗi lần state thay đổi là một version mới. Nếu state bị corrupt, bạn roll back về version trước.
Backend migration – Chuyển state từ nơi này sang nơi khác
Kịch bản hay gặp: bạn bắt đầu với local backend, sau đó team lớn hơn và cần chuyển sang S3.
Bước 1: Cập nhật config backend trong main.tf
# Trước: không có backend block (mặc định là local)
# Sau: thêm vào
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "ap-southeast-1"
}
}
Bước 2: Chạy lệnh migrate
terraform init -migrate-state
Terraform sẽ hỏi xác nhận:
Initializing the backend...
Do you want to copy existing state to the new backend?
Pre-existing state was found while migrating the previous "local" 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, Terraform copy state hiện tại lên S3 và từ đó trở đi dùng S3 làm backend.
Ngược lại, nếu muốn pull state về local (ví dụ để debug):
terraform state pull > backup.tfstate
Tóm lại
- State file lưu toàn bộ thông tin về hạ tầng hiện tại. Mất hoặc corrupt state file là vấn đề nghiêm trọng.
- Local backend ổn cho cá nhân, không phù hợp cho team.
- S3 backend là lựa chọn phổ biến nhất với AWS – kết hợp S3 lưu state và DynamoDB cho state locking.
terraform init -migrate-stateđể chuyển state giữa các backend mà không mất dữ liệu.
Bước tiếp theo nên tìm hiểu về Terraform Workspaces – cách quản lý nhiều môi trường (dev/staging/prod) với cùng một codebase mà không cần tạo thư mục riêng cho từng môi trường.