search

Terraform Remote Backend – Lưu State trên AWS S3

calendar_today Đăng ngày: 29/04/2026

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.