Bài giảng: hiểu luồng trước khi chạy lệnh
Bài toán: Chuẩn bị repository, credential và backend rồi tạo Jenkins pipeline có kiểm tra, plan, approval và apply rõ ràng.
terraform fmt
terraform init
terraform validate
terraform plan
terraform apply
terraform plan -destroy
terraform destroyJenkins không nên giữ secret trong Jenkinsfile
Jenkins cần checkout repository, cài Terraform/provider, truy cập backend và cloud role. Dùng Credentials Binding hoặc cloud integration; không viết access key trực tiếp trong Jenkinsfile.
pipeline {
agent any
stages {
stage('Check') {
steps {
sh 'terraform fmt -check -recursive'
sh 'terraform init -backend=false'
sh 'terraform validate'
}
}
stage('Plan') {
steps {
sh 'terraform init'
sh 'terraform plan -var-file=env/dev.tfvars -out=tfplan'
archiveArtifacts artifacts: 'tfplan', fingerprint: true
}
}
stage('Apply') {
input { message 'Cho phép apply hạ tầng?' }
steps { sh 'terraform apply -auto-approve tfplan' }
}
}
}
input là ví dụ approval đơn giản; production nên giới hạn người được approve, dùng lock cho job và ghi lại change ticket.
S3 backend và credential
Jenkins agent không nên lưu state ở workspace local. Cấu hình S3 backend dùng key riêng cho project/environment, bật versioning/encryption/locking. Nếu agent là ephemeral, mọi thứ cần thiết phải được cài hoặc đóng gói trong image runner.
AWS credential tốt nhất là IAM role của agent hoặc OIDC assume role. Nếu phải dùng credential binding, đặt quyền nhỏ nhất: đọc backend, ghi đúng prefix và các quyền resource cần cho job.
Tránh hai pipeline đụng state
Dùng disableConcurrentBuilds() hoặc lock plugin:
options { disableConcurrentBuilds() }
Đây là lớp bảo vệ phía CI; backend locking vẫn phải bật vì có thể có một runner khác hoặc lệnh chạy ngoài Jenkins.
Debug có kỷ luật
Khi job fail, lưu Terraform version, provider lock và command đã chạy. Không bật TF_LOG=TRACE trên production một cách vô thức vì log có thể chứa request payload, token hoặc dữ liệu state. Nếu cần debug, giới hạn thời gian, quyền xem và xóa artifact sau khi điều tra.
Bảo vệ Jenkinsfile
Jenkinsfile là code có quyền thay đổi hạ tầng, nên cần được review như application code:
- Chỉ build từ branch/tag được bảo vệ.
- Dùng agent ephemeral nếu có thể, tránh lưu state/credential trên workspace.
- Xóa workspace sau run và không in secret ra console.
- Tách job plan và apply, giới hạn người approve production.
- Ghim phiên bản Terraform/provider và kiểm tra checksum.
Thử một thay đổi vô hại như tag trước. Khi rollback, apply một commit đã review hoặc revert commit rồi tạo plan mới; không tự ý lấy file state cũ và ghi đè backend.
Expected pipeline và failure drills
Expected state của Jenkins job là agent ephemeral/được kiểm soát, Terraform/provider version lock đúng, check không credential, plan dùng backend/key/environment đúng, artifact được bảo vệ và apply chỉ chạy sau approval/lock. Mỗi run ghi commit SHA, actor/approver, plan summary, state workspace và smoke/rollback result; workspace không giữ state/secret sau cleanup.
Thực hiện các drill:
- Chạy build từ branch chưa protected hoặc dùng Terraform/provider lock khác, xác nhận pipeline dừng trước plan/apply.
- Cho hai build cùng workspace chạy song song, kiểm tra
disableConcurrentBuildsvà backend lock; không retry vô hạn hay-lock=false. - Mô phỏng credentials binding thiếu/sai, agent mất kết nối, backend unavailable và approval timeout; phân loại controller/agent/IAM/backend/policy, không in environment/TF_LOG TRACE bừa bãi.
- Tạo plan có destroy/IAM/firewall/database replacement, kiểm tra reviewer/approval/policy/artifact access/expiry; cleanup workspace và artifact sau run.
Quality gate
Pass khi Jenkinsfile được review/protected, plan/apply tách rõ, agent/credential/state isolation, CI và backend concurrency lock, artifact/secret hygiene, approval/policy cho high-risk changes, immutable commit/provider evidence và post-apply smoke/rollback runbook đầy đủ. Jenkins input step một mình không phải production approval control.