Pipeline nhỏ nhưng có guardrail
stages: [check, plan, apply]
fmt:
stage: check
script:
- terraform fmt -check -recursive
validate:
stage: check
script:
- terraform init -backend=false
- terraform validate
plan:
stage: plan
script:
- terraform init
- terraform plan -var-file=env/dev.tfvars -out=tfplan
artifacts:
paths: [tfplan]
expire_in: 1 day
apply_dev:
stage: apply
when: manual
script:
- terraform init
- terraform apply -auto-approve tfplan
Artifact plan phải được tạo từ cùng commit và provider lock file với bước apply. Nếu runner khác workspace, backend và credential phải được cấu hình giống nhau.
Tách môi trường
Một layout dễ theo dõi:
env/
├── dev.tfvars
└── prod.tfvars
modules/
main.tf
variables.tf
dev.tfvars và prod.tfvars chỉ chứa giá trị khác nhau, không copy toàn bộ resource. Production nên có protected branch, protected variable, runner phù hợp và manual approval.
Terraform workspaces: dùng khi nào?
Workspace cho phép một cấu hình có nhiều state:
terraform workspace new dev
terraform workspace select dev
terraform plan
Nó tiện cho các environment có cấu trúc giống nhau, nhưng dễ gây nhầm nếu tên workspace quyết định quyền production. Với hệ thống lớn, tách thư mục/root module hoặc HCP workspace thường minh bạch hơn.
Secret và lock
GitLab CI variables cần đánh dấu masked/protected. Dùng OIDC hoặc role ngắn hạn nếu cloud hỗ trợ, thay vì lưu access key lâu dài. State backend vẫn cần lock; hai pipeline cùng apply một state là lỗi thiết kế, không phải lý do để thêm retry vô hạn.
Review plan mà không làm lộ secret
Plan trong job log có thể chứa giá trị nhạy cảm hoặc đường dẫn nội bộ. Hãy giới hạn quyền đọc job/artifact, đặt thời gian hết hạn ngắn và không echo toàn bộ environment:
plan:
script:
- terraform plan -var-file=env/dev.tfvars -out=tfplan
- terraform show -no-color tfplan > plan.txt
artifacts:
access: developer
expire_in: 1 day
paths: [plan.txt, tfplan]
Trước production, thêm policy kiểm tra các hành động delete, thay đổi IAM và mở firewall. Mục tiêu của CI không phải làm apply nhanh nhất mà là làm thay đổi nguy hiểm trở nên dễ nhìn thấy và khó thực hiện nhầm.
Khi dùng nhiều environment, tách state key và job resource. Không để một biến ENV=prod duy nhất quyết định cả backend, account và credential; chỉ cần một variable sai là pipeline có thể apply nhầm account.
Bài tập
Thêm job plan_prod chỉ chạy khi thay đổi nhánh chính, hiển thị plan để review và yêu cầu apply_prod manual. Thử làm một thay đổi tag nhỏ để quan sát pipeline trước khi tạo resource tốn phí.
Nguồn tham khảo: Building CI/CD for Terraform with GitLab CI.