如何在GitLab CI/CD中集成Terraform并实现多目录脚本安全部署
Terraform多目录部署集成GitLab CI/CD的问题与解决方案
原始问题
我有一套按关注点拆分到不同目录的Terraform资源脚本,手动部署时会逐个进入目录执行terraform apply,每次都要先查看变更计划,再手动输入yes确认。现在想把这套流程集成到GitLab CI/CD里,但卡在了部署环节——apply需要手动输入确认,而用-auto-approve又太危险。
更新1:多目录计划输出疑问
所有资源脚本都在同一个仓库的不同目录下,且要通过同一条流水线创建,我不确定该怎么规划计划文件的输出。请问下面的流水线配置能不能在planoutput目录生成3个计划文件?
现有GitLab CI配置(.gitlab-ci.yml)
stages: - plan image: "docker/mycompany/terraform" plan: stage: plan script: - chmod +x ./scripts/dev.sh - ./scripts/dev.sh artifacts: paths: - planoutput
对应的执行脚本(scripts/dev.sh)
#!/bin/bash cd ${CI_PROJECT_DIR}/tf/kms/ terraform init terraform validate terraform plan -out=kms.tfplan cd ${CI_PROJECT_DIR}/tf/roles/ terraform init terraform validate terraform plan -out=roles.tfplan cd ${CI_PROJECT_DIR}/tf/lambda/ terraform init terraform validate terraform plan -out=lambda.tfplan
解决方案
1. 解决手动确认部署的风险问题
GitLab CI支持手动触发阶段,可以把流程拆成两个阶段规避风险:
plan阶段:自动执行,生成所有模块的变更计划并保存为artifactsapply阶段:设置为手动触发,只有人工确认计划无误后,再执行部署操作
这样既不用依赖危险的-auto-approve,又能保留人工审核的环节。
2. 修正多目录计划文件的输出路径
你当前的配置不会在planoutput目录生成计划文件——脚本里的terraform plan -out是把文件存在各自的Terraform模块目录(tf/kms/等)下,而非指定的planoutput目录。要实现目标,需要修改脚本:
修改后的dev.sh脚本:
#!/bin/bash # 先在项目根目录创建planoutput目录 mkdir -p ${CI_PROJECT_DIR}/planoutput # KMS模块生成计划到planoutput cd ${CI_PROJECT_DIR}/tf/kms/ terraform init terraform validate terraform plan -out=${CI_PROJECT_DIR}/planoutput/kms.tfplan # 角色模块生成计划到planoutput cd ${CI_PROJECT_DIR}/tf/roles/ terraform init terraform validate terraform plan -out=${CI_PROJECT_DIR}/planoutput/roles.tfplan # Lambda模块生成计划到planoutput cd ${CI_PROJECT_DIR}/tf/lambda/ terraform init terraform validate terraform plan -out=${CI_PROJECT_DIR}/planoutput/lambda.tfplan
调整后,脚本会把3个计划文件统一输出到planoutput目录,和你CI配置里的artifacts路径匹配,流水线执行后就能在artifacts中看到这3个文件。
3. 完整流水线配置示例
stages: - plan - apply image: "docker/mycompany/terraform" plan: stage: plan script: - chmod +x ./scripts/dev.sh - ./scripts/dev.sh artifacts: paths: - planoutput expire_in: 7d # 设置artifacts过期时间,避免冗余存储 apply_kms: stage: apply needs: [plan] when: manual # 手动触发开关 script: - cd ${CI_PROJECT_DIR}/tf/kms/ - terraform init - terraform apply ${CI_PROJECT_DIR}/planoutput/kms.tfplan apply_roles: stage: apply needs: [plan] when: manual script: - cd ${CI_PROJECT_DIR}/tf/roles/ - terraform init - terraform apply ${CI_PROJECT_DIR}/planoutput/roles.tfplan apply_lambda: stage: apply needs: [plan] when: manual script: - cd ${CI_PROJECT_DIR}/tf/lambda/ - terraform init - terraform apply ${CI_PROJECT_DIR}/planoutput/lambda.tfplan
这个配置会先自动完成所有模块的计划生成,之后你可以在GitLab流水线界面看到三个独立的apply任务,按需手动触发单个模块的部署,进一步降低误操作风险。
内容的提问来源于stack exchange,提问作者LP13
相关产品推荐
相关产品推荐

