如何在Jenkins Pipeline中使用Terraform命令并行运行多环境tfvars配置
问题解答
关于多tfvars文件传入的疑问
你提到的terraform plan -var-file=[xxx,xxx]写法不生效,原因如下:
- Terraform的
-var-file参数支持重复指定,但格式为多次单独传参:terraform plan -var-file=file1.tfvars -var-file=file2.tfvars - 但这种写法完全不适合你的场景:不同区域、不同环境的
.tfvars文件通常会有同名变量(比如region、env_type),后传入的文件变量会覆盖前面的,最终只会生效最后一个文件的配置,无法实现多区域/多环境独立部署的需求。 - 不同环境、不同区域的Terraform部署本身就是独立的执行流程,必须分开执行
plan和apply,不能合并到一次命令中。
Jenkins Pipeline并行执行实现方案
你可以用Jenkins Pipeline的parallel语法,把不同区域、不同环境的部署任务定义为并行任务,示例改造后的Pipeline如下:
pipeline { agent none triggers { cron('0 9 * * *') // 每天9点定时执行 } stages { stage('Pre-deploy stacks') { agent { node { label 'deploy-python36' } } steps { sh 'cf sync --confirm cfn/stacks.yml' sh 'curl https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo | tee /etc/yum.repos.d/hashicorp.repo && yum install terraform -y' } } stage('TF Initialization') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { sh 'terraform init' } } } stage('沙箱环境并行Plan') { parallel { stage('DE沙箱Plan') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { // 切换到对应workspace,避免状态冲突,提前创建好对应workspace即可 sh 'terraform workspace select de-sandbox' // plan结果输出到文件,后续apply直接用该文件保证一致性 sh 'terraform plan -var-file=conf/tf-de-sandbox.tfvars -out=de-sandbox.tfplan' } } } stage('FR沙箱Plan') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { sh 'terraform workspace select fr-sandbox' sh 'terraform plan -var-file=conf/tf-fr-sandbox.tfvars -out=fr-sandbox.tfplan' } } } } } // 沙箱Apply阶段,可根据需求加审批 stage('沙箱环境并行Apply') { parallel { stage('DE沙箱Apply') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { sh 'terraform workspace select de-sandbox' sh 'terraform apply -input=false de-sandbox.tfplan' } } } stage('FR沙箱Apply') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { sh 'terraform workspace select fr-sandbox' sh 'terraform apply -input=false fr-sandbox.tfplan' } } } } } // 生产环境流程和沙箱一致,建议加人工审批步骤再执行Apply stage('生产环境Plan') { when { // 可加参数控制只有手动触发时才执行生产流程 expression { params.DEPLOY_PROD == true } } parallel { stage('DE生产Plan') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { sh 'terraform workspace select de-prod' sh 'terraform plan -var-file=conf/tf-de-prod.tfvars -out=de-prod.tfplan' } } } stage('FR生产Plan') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { sh 'terraform workspace select fr-prod' sh 'terraform plan -var-file=conf/tf-fr-prod.tfvars -out=fr-prod.tfplan' } } } } } stage('生产环境审批') { when { expression { params.DEPLOY_PROD == true } } steps { input message: '确认执行生产环境部署?', ok: '确认' } } stage('生产环境并行Apply') { when { expression { params.DEPLOY_PROD == true } } parallel { stage('DE生产Apply') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { sh 'terraform workspace select de-prod' sh 'terraform apply -input=false de-prod.tfplan' } } } stage('FR生产Apply') { agent { node { label 'deploy-python36' } } steps { dir('./tf') { sh 'terraform workspace select fr-prod' sh 'terraform apply -input=false fr-prod.tfplan' } } } } } } }
注意事项
- 提前创建Terraform Workspace区分不同环境和区域,执行
terraform workspace new [workspace名]即可,避免不同部署任务的状态文件互相覆盖 - 确保你的Terraform后端存储(如S3、GCS)开启了状态锁,避免并发操作导致状态文件损坏
- plan输出的tfplan文件只对当前执行的workspace有效,不要跨workspace混用
内容的提问来源于stack exchange,提问作者Farukh Khan
相关产品推荐
相关产品推荐

