ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Terraform实战12:CI/CD集成——GitLab CI + Terraform自动化

Terraform实战12:CI/CD集成——GitLab CI + Terraform自动化 Terraform实战12CI/CD集成——GitLab CI Terraform自动化本篇目标把Terraform集成到GitLab CI Pipeline中实现基础设施变更的自动化提MR自动plan预览审批合并后自动apply执行。学完本篇你将掌握GitLab CI Pipeline配置.gitlab-ci.ymlTerraform在CI中的标准工作流Plan结果的artifact传递多环境Pipeline设计prod环境的手动审批机制CI中的凭证安全管理前置条件熟悉GitLab CI你工作中就在用理解Terraform的init/plan/apply流程为什么需要CI/CD集成手动在本地执行terraform的问题问题后果每个人本地执行不知道谁改了什么没有审批流程直接apply没review可能误操作生产环境凭证在本地不安全离职后风险没有执行记录出问题追溯困难CI/CD集成后所有变更通过MR → 有review、有记录Plan结果自动展示 → reviewer能看到会改什么Apply需要审批 → 防止误操作凭证在CI Variables中 → 不在本地可以随时撤销标准工作流开发者修改 .tf 文件 │ ▼ 提交MR ┌─────────────────┐ │ validate │ ← 语法检查 格式检查 └────────┬────────┘ ▼ ┌─────────────────┐ │ plan │ ← 预览变更结果显示在MR中 └────────┬────────┘ ▼ Reviewer审批合并MR ┌─────────────────┐ │ apply │ ← 执行变更dev自动prod手动确认 └─────────────────┘完整Pipeline配置基础版.gitlab-ci.ymlstages:-validate-plan-apply-destroyvariables:TF_VERSION:1.9.0TF_ROOT:${CI_PROJECT_DIR}/infrastructure# 基础镜像和初始化default:image:name:hashicorp/terraform:${TF_VERSION}entrypoint:[]before_script:-cd ${TF_ROOT}-terraform init-inputfalse# Stage 1语法校验每次push自动执行validate:stage:validatescript:-terraform validate-terraform fmt-check-diffrules:-if:$CI_PIPELINE_SOURCE merge_request_event-if:$CI_COMMIT_BRANCH main# Stage 2Plan预览变更保存plan文件plan:stage:planscript:-terraform plan-outtfplan-inputfalse-terraform show-no-color tfplanplan_output.txtartifacts:paths:-${TF_ROOT}/tfplan-${TF_ROOT}/plan_output.txtexpire_in:1 hourrules:-if:$CI_PIPELINE_SOURCE merge_request_event-if:$CI_COMMIT_BRANCH main# Stage 3a自动Applymain分支push时apply:auto:stage:applyscript:-terraform apply-auto-approve-inputfalse tfplandependencies:-planrules:-if:$CI_COMMIT_BRANCH mainwhen:on_success# Stage 3b手动ApplyMR中点击按钮apply:manual:stage:applyscript:-terraform apply-auto-approve-inputfalse tfplandependencies:-planrules:-if:$CI_PIPELINE_SOURCE merge_request_eventwhen:manualallow_failure:true# Stage 4Destroy手动触发destroy:stage:destroyscript:-terraform destroy-auto-approve-inputfalserules:-if:$CI_COMMIT_BRANCH mainwhen:manualallow_failure:true进阶版多环境Pipelinestages:-validate-plan-applyvariables:TF_VERSION:1.9.0default:image:name:hashicorp/terraform:${TF_VERSION}entrypoint:[]# 模板复用.terraform_init:terraform_initbefore_script:-cd infrastructure/environments/${ENVIRONMENT}-terraform init-inputfalse# Plan:devdev目录变更时触发plan:dev:stage:plan:*terraform_initvariables:ENVIRONMENT:devscript:-terraform plan-outtfplan-inputfalseartifacts:paths:-infrastructure/environments/dev/tfplanexpire_in:1 hourrules:-if:$CI_COMMIT_BRANCH mainchanges:-infrastructure/environments/dev/**/*-infrastructure/modules/**/*# Plan:prodplan:prod:stage:plan:*terraform_initvariables:ENVIRONMENT:prodscript:-terraform plan-outtfplan-inputfalseartifacts:paths:-infrastructure/environments/prod/tfplanexpire_in:1 hourrules:-if:$CI_COMMIT_BRANCH mainchanges:-infrastructure/environments/prod/**/*-infrastructure/modules/**/*# Apply:dev自动apply:dev:stage:apply:*terraform_initvariables:ENVIRONMENT:devscript:-terraform apply-auto-approve-inputfalse tfplandependencies:-plan:devrules:-if:$CI_COMMIT_BRANCH mainchanges:-infrastructure/environments/dev/**/*-infrastructure/modules/**/*# Apply:prod手动审批apply:prod:stage:apply:*terraform_initvariables:ENVIRONMENT:prodscript:-terraform apply-auto-approve-inputfalse tfplandependencies:-plan:prodrules:-if:$CI_COMMIT_BRANCH mainchanges:-infrastructure/environments/prod/**/*-infrastructure/modules/**/*when:manual# prod必须手动确认关键配置说明GitLab CI Variables凭证管理在 GitLab → Settings → CI/CD → Variables 中添加VariableProtectedMasked说明AWS_ACCESS_KEY_ID✅✅AWS AKAWS_SECRET_ACCESS_KEY✅✅AWS SKAWS_DEFAULT_REGION❌❌区域Protected 只有protected分支main能用 → 防止feature分支随便applyMasked 日志中不显示明文 → 防止泄露Plan文件传递artifactsplan:artifacts:paths:-${TF_ROOT}/tfplan# plan阶段保存expire_in:1 hourapply:dependencies:-plan# apply阶段下载plan的artifactscript:-terraform apply tfplan# 用保存的plan执行不重新plan为什么要这样做保证plan和apply是同一个计划防止plan和apply之间有人改了代码导致不一致changes触发只改了相关目录才执行rules:-if:$CI_COMMIT_BRANCH mainchanges:-infrastructure/environments/dev/**/*# dev目录变更-infrastructure/modules/**/*# 共用模块变更改了dev的配置不会触发prod的pipeline精准控制。when: manual手动审批apply:prod:when:manual# 需要人工点击按钮才执行prod环境的apply不自动执行必须有人在GitLab UI中点击Run按钮确认。项目目录结构建议your-repo/ ├── .gitlab-ci.yml # Pipeline配置 ├── infrastructure/ │ ├── modules/ # 共用模块 │ │ └── vpc/ │ └── environments/ # 各环境 │ ├── dev/ │ │ ├── main.tf │ │ ├── variables.tf │ │ └── terraform.tfvars │ └── prod/ │ ├── main.tf │ ├── variables.tf │ └── terraform.tfvars └── README.md延伸思考面试常见问题面试问题答案要点你们Terraform怎么跑的GitLab CI集成MR时自动plan合并后applyprod手动审批怎么防止误操作生产prod的apply设为manual Protected Variables MR审批CI中凭证怎么管理GitLab CI VariablesProtectedMasked不在代码中plan和apply之间代码变了怎么办用-out保存plan文件apply时用同一个plan不重新生成多人同时apply会冲突吗远程State用DynamoDB锁同时只能一人操作费用说明本篇不创建AWS资源费用为0。只是编写Pipeline配置文件。小结本篇核心收获标准工作流validate → plan → apply通过MR驱动Plan文件传递artifacts保证plan和apply一致性prod手动审批when: manual防止自动部署到生产凭证安全GitLab Variables Protected Maskedchanges触发精准控制哪个环境的pipeline被触发这跟你工作中的GitLab CI是同一套逻辑——只是跑的是Terraform而不是构建镜像下一篇预告Terraform实战13安全最佳实践——IAM、加密与合规检查下一篇我们将学习用tfsec/checkov扫描Terraform代码的安全问题IAM最小权限原则的实现加密配置的最佳实践如何在CI中集成安全扫描参考链接本系列配套代码GitHubGitLab CI Terraform官方指南Terraform CI/CD最佳实践GitLab CI Variables文档GitLab CI rules文档
返回列表