Các bài trước đã giới thiệu từng công cụ riêng lẻ (Claude Code, OpenCode, Gemini CLI, Cursor) kết nối với Terraform MCP. Bài này ghép mọi thứ lại thành một quy trình end-to-end hoàn chỉnh, mô phỏng đúng một ngày làm việc thật: nhận yêu cầu thay đổi hạ tầng, dùng AI hỗ trợ viết và review, mở PR có plan summary dễ đọc, và apply an toàn. Đây là workflow bạn có thể áp dụng nguyên vẹn cho team của mình, không phải lý thuyết trừu tượng.
Tổng Quan Workflow: Từ Yêu Cầu Đến Thay Đổi Hạ Tầng Được Apply An Toàn
Trước khi vào chi tiết từng bước, hình dung toàn cảnh quy trình 3 bước chính, mỗi bước có ranh giới rõ ràng giữa việc AI làm và việc con người quyết định:
[Yêu cầu nghiệp vụ]
│
▼
Bước 1: AI hỗ trợ viết Terraform config + tự chạy validate/plan
│
▼
Bước 2: AI review plan (destructive change, drift, policy) → báo cáo rủi ro
│
▼
[Con người review PR, đọc báo cáo rủi ro, quyết định approve]
│
▼
Bước 3: Mở PR có plan summary người đọc được → CI apply sau khi merge
Nguyên tắc xuyên suốt: AI luôn đứng ở vai trò tăng tốc và tăng chất lượng review (đọc plan nhanh hơn, phát hiện rủi ro con người dễ bỏ sót), nhưng quyết định cuối cùng — approve PR, chạy apply — luôn thuộc về con người có quyền hạn tương ứng. Đây không phải nguyên tắc cứng nhắc vì "sợ AI" mà vì bản chất hạ tầng: sai sót application có thể rollback bằng redeploy, sai sót infrastructure (đặc biệt liên quan resource stateful) có thể không thể đảo ngược.
Mẹo: Vẽ sơ đồ workflow này (hoặc bản tương tự phù hợp với team bạn) và đặt ngay đầu file
CONTRIBUTING.mdcủa repo infra — mọi thành viên mới, dù dùng AI agent hay không, đều cần hiểu ranh giới rõ ràng giữa "AI hỗ trợ" và "người quyết định" trước khi được cấp quyền merge vào nhánh chính.
Bước 1: Viết Thay Đổi Và Sinh Plan Với Sự Hỗ Trợ Của AI
Giả sử yêu cầu nghiệp vụ: "Thêm read replica cho RDS PostgreSQL hiện tại để giảm tải cho reporting service." Đây là thay đổi vừa đủ phức tạp để minh họa toàn bộ quy trình — cần hiểu rõ Terraform, có rủi ro thật, nhưng không quá lớn để làm ví dụ dài dòng.
Bắt đầu bằng branch mới và prompt cho agent (dùng Claude Code hoặc Cursor, tùy công cụ team bạn chọn):
git checkout -b infra/add-rds-read-replica
Thêm một RDS read replica cho aws_db_instance.postgres hiện tại
trong module database. Yêu cầu:
- instance_class giống instance chính (db.r6g.large)
- Đặt trong subnet group riêng cho read replica, cùng VPC
- Không publicly accessible
- Thêm output replica_endpoint
Sau khi viết xong, chạy terraform_validate rồi terraform_plan,
và cho tôi biết plan có resource nào bị destroy/replace không.
Agent sinh code:
resource "aws_db_instance" "postgres_replica" {
identifier = "acme-prod-db-replica"
replicate_source_db = aws_db_instance.postgres.identifier
instance_class = aws_db_instance.postgres.instance_class
publicly_accessible = false
db_subnet_group_name = aws_db_subnet_group.replica.name
skip_final_snapshot = true
tags = {
Role = "read-replica"
}
}
output "replica_endpoint" {
value = aws_db_instance.postgres_replica.endpoint
}
Sau khi chạy terraform_validate (pass) và terraform_plan, agent báo cáo: "Plan: 3 to add (db_subnet_group.replica, aws_db_instance.postgres_replica, output mới), 0 to change, 0 to destroy." Đây là dấu hiệu tốt — thay đổi thuần "add", không động vào resource hiện tại. Nhưng đừng dừng ở đây; luôn tiếp tục sang bước review sâu hơn ở phần kế tiếp, vì "0 to destroy" chỉ là một góc nhìn, chưa phải toàn bộ rủi ro cần xét (ví dụ chi phí phát sinh, policy compliance).
Mẹo: Ngay ở bước viết code, luôn yêu cầu agent chạy
validatevàplantrong CÙNG một lượt trước khi bạn xem code lần đầu — việc này lọc bỏ ngay các lỗi cú pháp cơ bản, giúp bạn tập trung thời gian review vào logic nghiệp vụ và rủi ro thật, không phải bắt lỗi thiếu dấu ngoặc.
Bước 2: AI Review Plan — Destructive Change, Drift Và Vi Phạm Policy
Đây là bước giá trị cao nhất của cả workflow. Sau khi có plan "sạch" ở bước 1, chạy một lượt review sâu hơn, tập trung vào ba khía cạnh: thay đổi phá hủy (destructive), configuration drift, và vi phạm policy nội bộ (ví dụ naming convention, tagging bắt buộc, region được phép).
Review plan này theo checklist:
1. Có resource nào bị destroy hoặc replace không? Nếu có, resource
nào là stateful (database, storage, queue)?
2. Chạy plan -refresh-only để kiểm tra có drift nào giữa state
hiện tại và hạ tầng thật trước khi apply thay đổi mới không?
3. Mọi resource mới có đủ tag bắt buộc (Environment, Owner,
CostCenter) theo policy của team không?
4. aws_db_instance.postgres_replica có publicly_accessible = false
như yêu cầu security baseline không?
Kết quả review agent trả về:
1. Không có destroy/replace. An toàn về mặt data loss.
2. Refresh-only cho thấy 1 drift: aws_security_group.db có thêm
1 ingress rule (port 5432 từ 203.0.113.0/24) không có trong
config — có khả năng ai đó thêm tay qua console để debug,
CẦN XÁC NHẬN trước khi tiếp tục vì rule này không có trong
Terraform, sẽ không được quản lý và có thể là lỗ hổng bảo mật
nếu không chủ ý.
3. aws_db_instance.postgres_replica THIẾU tag CostCenter -
cần bổ sung theo policy.
4. publicly_accessible = false - ĐÚNG yêu cầu.
Đây chính là giá trị thực tế của agentic review: phát hiện một security group rule "lạ" (rất có thể là backdoor debug quên xóa) hoàn toàn không liên quan gì đến thay đổi bạn đang làm, nhưng lộ ra vì bước refresh-only. Nếu chỉ review plan thông thường (không refresh-only), drift này sẽ ẩn đi vì Terraform chỉ diff giữa state cũ và config mới, không biết gì về thay đổi ngoài luồng trên cloud thật.
Sửa lại 2 vấn đề trước khi tiếp tục: thêm tag CostCenter, và báo cáo riêng cho security team về ingress rule lạ (xử lý độc lập, không gộp vào PR read replica này).
Mẹo: Luôn chạy
terraform plan -refresh-onlynhư một bước bắt buộc trong checklist review, không chỉ chạy plan thường — nhiều vấn đề bảo mật nghiêm trọng nhất (thay đổi ngoài luồng không qua Terraform) chỉ lộ ra ở bước refresh-only, và agent rất phù hợp để chạy việc này lặp lại mỗi PR mà không tốn công con người.
Bước 3: Mở PR Với Plan Summary Dễ Đọc Và Apply
Sau khi review sạch (đã bổ sung tag, đã báo cáo drift ngoài luồng cho đúng người xử lý), bước cuối là đóng gói thay đổi thành PR có đầy đủ thông tin cho reviewer — không yêu cầu reviewer phải tự chạy lại plan mới hiểu được thay đổi.
Viết PR description cho thay đổi này, gồm:
- Tóm tắt 1-2 câu mục đích thay đổi (bằng tiếng Việt)
- Plan summary dạng bảng: resource, action, lý do
- Rủi ro đã kiểm tra (checklist ở bước 2) và kết quả
- Chi phí ước tính phát sinh (db.r6g.large read replica,
region ap-southeast-1)
PR description mẫu agent sinh ra:
## Mục đích
Thêm RDS read replica cho PostgreSQL production để giảm tải
query reporting, tách khỏi traffic ghi của instance chính.
## Plan Summary
| Resource | Action | Lý do |
|---|---|---|
| aws_db_subnet_group.replica | create | Subnet group riêng cho replica |
| aws_db_instance.postgres_replica | create | Read replica từ postgres chính |
| output.replica_endpoint | create | Expose endpoint cho reporting service |
## Rủi ro đã kiểm tra
- Không có destroy/replace trên resource hiện tại — an toàn data.
- Drift phát hiện (security group rule lạ) đã báo riêng cho
security team, KHÔNG thuộc phạm vi PR này.
- Đã bổ sung tag CostCenter theo policy.
## Chi phí ước tính
+1x db.r6g.large tại ap-southeast-1 ≈ $140/tháng (on-demand),
chưa gồm storage. Team nên xác nhận có nằm trong budget quý này.
Sau khi PR được một reviewer là người có quyền hạn phù hợp approve, CI pipeline (không phải agent chạy trực tiếp từ máy cá nhân) chạy terraform apply trong môi trường có kiểm soát, log đầy đủ, và credentials riêng có quyền write — tách biệt hoàn toàn khỏi credentials read-only mà agent dùng ở bước 1-2.
on:
pull_request:
types: [closed]
jobs:
apply:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
environment: production-apply # yêu cầu approval riêng trên GitHub Environment
steps:
- uses: actions/checkout@v4
- run: terraform init
- run: terraform apply -auto-approve tfplan
Mẹo: Dùng GitHub Environment (hoặc tương đương trên GitLab/CI khác) với required reviewer riêng cho job apply, tách biệt hoàn toàn khỏi quyền merge PR — một người có thể approve merge code nhưng không nhất thiết có quyền trigger apply hạ tầng production, đây là lớp kiểm soát kép (two-person rule) rất đáng đầu tư cho môi trường production.
Nhìn Lại Toàn Bộ Workflow: Điều Gì Làm Nên Một Quy Trình An Toàn
Nhìn lại ví dụ read replica xuyên suốt bài, ba yếu tố khiến workflow này an toàn dù có AI can thiệp sâu ở cả 2 bước đầu:
- AI luôn dừng ở "báo cáo rủi ro", không tự quyết "chấp nhận rủi ro". Việc phát hiện security group rule lạ là agent làm, nhưng quyết định "báo security team, tách khỏi PR này" là con người quyết.
- Refresh-only là bước không thể bỏ qua. Đây là bước duy nhất lộ ra thay đổi ngoài luồng — nếu bỏ qua, PR này có thể merge và apply "sạch sẽ" trong khi vẫn tồn tại một lỗ hổng bảo mật không ai biết.
- Credentials và quyền hạn được tách theo từng vai trò cụ thể (agent review = read-only, CI apply = write nhưng có gate riêng) — không có một credential "vạn năng" nào chạy suốt từ đầu đến cuối workflow.
Workflow này không cố định — điều chỉnh số bước review, checklist policy theo đặc thù team bạn. Nhưng ba nguyên tắc trên (AI báo cáo không tự quyết, refresh-only bắt buộc, tách quyền theo vai trò) nên giữ nguyên bất kể bạn dùng Claude Code, OpenCode, Gemini CLI hay Cursor làm công cụ chính.
Mẹo: Sau vài tuần áp dụng workflow này, thu thập lại các trường hợp AI phát hiện đúng rủi ro (và cả trường hợp báo sai/bỏ sót) thành một file "lessons learned" trong repo — dữ liệu này giúp bạn tinh chỉnh checklist review ở bước 2 ngày càng sát với rủi ro thật của hạ tầng riêng team bạn, thay vì dùng checklist chung chung mãi.