news 2026/8/13 10:56:36

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Terraform实战12:CI/CD集成——GitLab CI + Terraform自动化

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

本篇目标

把Terraform集成到GitLab CI Pipeline中,实现基础设施变更的自动化:提MR自动plan预览,审批合并后自动apply执行。

学完本篇你将掌握:

  • GitLab CI Pipeline配置(.gitlab-ci.yml)
  • Terraform在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.yml

stages:-validate-plan-apply-destroyvariables:TF_VERSION:"1.9.0"TF_ROOT:"${CI_PROJECT_DIR}/infrastructure"# 基础镜像和初始化default:image:name:hashicorp/terraform:${TF_VERSION}entrypoint:[""]before_script:-cd ${TF_ROOT}-terraform init-input=false# 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 2:Plan(预览变更,保存plan文件)plan:stage:planscript:-terraform plan-out=tfplan-input=false-terraform show-no-color tfplan>plan_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:自动Apply(main分支push时)apply:auto:stage:applyscript:-terraform apply-auto-approve-input=false tfplandependencies:-planrules:-if:'$CI_COMMIT_BRANCH == "main"'when:on_success# Stage 3b:手动Apply(MR中点击按钮)apply:manual:stage:applyscript:-terraform apply-auto-approve-input=false tfplandependencies:-planrules:-if:'$CI_PIPELINE_SOURCE == "merge_request_event"'when:manualallow_failure:true# Stage 4:Destroy(手动触发)destroy:stage:destroyscript:-terraform destroy-auto-approve-input=falserules:-if:'$CI_COMMIT_BRANCH == "main"'when:manualallow_failure:true

进阶版:多环境Pipeline

stages:-validate-plan-applyvariables:TF_VERSION:"1.9.0"default:image:name:hashicorp/terraform:${TF_VERSION}entrypoint:[""]# 模板复用.terraform_init:&terraform_initbefore_script:-cd infrastructure/environments/${ENVIRONMENT}-terraform init-input=false# Plan:dev(dev目录变更时触发)plan:dev:stage:plan<<:*terraform_initvariables:ENVIRONMENT:devscript:-terraform plan-out=tfplan-input=falseartifacts:paths:-infrastructure/environments/dev/tfplanexpire_in:1 hourrules:-if:'$CI_COMMIT_BRANCH == "main"'changes:-infrastructure/environments/dev/**/*-infrastructure/modules/**/*# Plan:prodplan:prod:stage:plan<<:*terraform_initvariables:ENVIRONMENT:prodscript:-terraform plan-out=tfplan-input=falseartifacts:paths:-infrastructure/environments/prod/tfplanexpire_in:1 hourrules:-if:'$CI_COMMIT_BRANCH == "main"'changes:-infrastructure/environments/prod/**/*-infrastructure/modules/**/*# Apply:dev(自动)apply:dev:stage:apply<<:*terraform_initvariables:ENVIRONMENT:devscript:-terraform apply-auto-approve-input=false tfplandependencies:-plan:devrules:-if:'$CI_COMMIT_BRANCH == "main"'changes:-infrastructure/environments/dev/**/*-infrastructure/modules/**/*# Apply:prod(手动审批!)apply:prod:stage:apply<<:*terraform_initvariables:ENVIRONMENT:prodscript:-terraform apply-auto-approve-input=false tfplandependencies:-plan:prodrules:-if:'$CI_COMMIT_BRANCH == "main"'changes:-infrastructure/environments/prod/**/*-infrastructure/modules/**/*when:manual# prod必须手动确认

关键配置说明

GitLab CI Variables(凭证管理)

在 GitLab → Settings → CI/CD → Variables 中添加:

VariableProtectedMasked说明
AWS_ACCESS_KEY_IDAWS AK
AWS_SECRET_ACCESS_KEYAWS SK
AWS_DEFAULT_REGION区域
  • Protected= 只有protected分支(main)能用 → 防止feature分支随便apply
  • Masked= 日志中不显示明文 → 防止泄露

Plan文件传递(artifacts)

plan: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 == "main"'changes:-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,合并后apply,prod手动审批
怎么防止误操作生产?prod的apply设为manual + Protected Variables + MR审批
CI中凭证怎么管理?GitLab CI Variables,Protected+Masked,不在代码中
plan和apply之间代码变了怎么办?用-out保存plan文件,apply时用同一个plan,不重新生成
多人同时apply会冲突吗?远程State用DynamoDB锁,同时只能一人操作

费用说明

本篇不创建AWS资源,费用为0。只是编写Pipeline配置文件。


小结

本篇核心收获:

  1. 标准工作流:validate → plan → apply,通过MR驱动
  2. Plan文件传递:artifacts保证plan和apply一致性
  3. prod手动审批when: manual防止自动部署到生产
  4. 凭证安全:GitLab Variables + Protected + Masked
  5. changes触发:精准控制哪个环境的pipeline被触发
  6. 这跟你工作中的GitLab CI是同一套逻辑——只是跑的是Terraform而不是构建镜像

下一篇预告

Terraform实战13:安全最佳实践——IAM、加密与合规检查

下一篇我们将学习:

  • 用tfsec/checkov扫描Terraform代码的安全问题
  • IAM最小权限原则的实现
  • 加密配置的最佳实践
  • 如何在CI中集成安全扫描

参考链接

  • 本系列配套代码(GitHub)
  • GitLab CI + Terraform官方指南
  • Terraform CI/CD最佳实践
  • GitLab CI Variables文档
  • GitLab CI rules文档
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/13 10:55:37

Python字符串与列表核心方法全解析:从面试考点到工程实践

1. 面试题背后的核心考察点面试官问“说一下 Python 中常用的字符串和数组的方法有哪些”&#xff0c;这绝对不是一个让你像背字典一样罗列 API 的问题。我面过不少人&#xff0c;也被人面过&#xff0c;这道题几乎是 Python 技术面的“保留曲目”。它的潜台词是&#xff1a;“…

作者头像 李华
网站建设 2026/8/13 10:55:37

一文吃透 KMS_VL_ALL_AIO:Windows 与 Office 激活问题的高效自救指南

一文吃透 KMS_VL_ALL_AIO&#xff1a;Windows 与 Office 激活问题的高效自救指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 先讲一个你可能经历过的场景 下午三点&#xff0c;正赶着改一份…

作者头像 李华
网站建设 2026/8/13 10:55:32

Galgame 翻译器 YUKI 上手指南:4 步玩转日文实时翻译

Galgame 翻译器 YUKI 上手指南&#xff1a;4 步玩转日文实时翻译 【免费下载链接】YUKI YUKI Galgame Translator 项目地址: https://gitcode.com/gh_mirrors/yu/YUKI 很多想玩日文视觉小说&#xff08;Galgame&#xff09;的人卡在同一个地方&#xff1a;游戏下载好了&…

作者头像 李华
网站建设 2026/8/13 10:53:00

Vue 3 配置驱动式搜索组件封装:从 Schema 设计到高级功能实现

1. 项目缘起&#xff1a;为什么我们需要一个高度封装的搜索组件&#xff1f; 在后台管理系统、数据中台这类项目中&#xff0c;搜索功能几乎是每个列表页的标配。回想一下你最近参与的项目&#xff0c;是不是经常遇到这样的场景&#xff1a;产品经理拿着原型图过来&#xff0c;…

作者头像 李华
网站建设 2026/8/13 10:52:25

边玩边译:YUKI Galgame 翻译器从下载到进阶的完整指南

边玩边译&#xff1a;YUKI Galgame 翻译器从下载到进阶的完整指南 【免费下载链接】YUKI YUKI Galgame Translator 项目地址: https://gitcode.com/gh_mirrors/yu/YUKI 你下载了一部心心念念的日文 Galgame&#xff0c;安装好、点开&#xff0c;然后面对满屏假名陷入沉默…

作者头像 李华