You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多环境Terraform项目的分支策略与CI/CD管道配置咨询

Terraform多环境项目分支与CI/CD实践问题解答

问题背景

参考HashiCorp官方文档搭建了基于modules的多环境Terraform项目,模块包含storage、compute、database,环境目录有development、stage、production,文件结构如下:

── modules
  ├── compute 
    │   ├── main.tf  
    │   ├── outputs.tf
    │   ├── variables.tf
  ├── database
  ├── storage
── development
   ├── config.tf
   ├── main.tf
   ├── outputs.tf
   ├── provider.tf
   ├── variables.tf
── stage
── production

已成功部署production环境,现在要部署staging和development环境,将development环境代码提交到GitHub的development分支后产生困惑:原本计划创建staging、production分支,但每个分支会包含三个环境目录,导致代码重复;想通过GitHub Actions实现分支推送时自动执行对应环境的terraform apply,咨询以下问题:

  1. 分支内保留多环境代码是否可行?
  2. 如何合理组织GitHub分支?
  3. 正确的CI/CD pipeline阶段应如何设置?

问题解答

1. 分支内保留多环境代码是否可行?

完全可行,但并非最优解:

  • 可行原因:多环境代码在同一分支中,模块变更可一次性同步到所有环境,无需跨分支合并模块代码,避免模块版本不一致的问题。
  • 弊端:若误修改分支内其他环境的配置,容易触发非目标环境的误部署;冗余的环境目录会增加仓库体积,也容易让新人混淆环境边界。

2. 如何合理组织GitHub分支?

推荐两种主流方案,可根据团队规模和协作流程选择:

方案一:单分支+环境目录(适合中小团队)

  • 核心逻辑:仅保留一个主分支(如main),所有环境目录(development/stage/production)都放在该分支内。
  • 分支策略:
    • 开发新功能或修改模块时,从main切出特性分支(如feat/add-redis-module),测试通过后合并回main。
    • 环境配置变更直接在main分支的对应环境目录中修改,通过CI/CD规则控制仅部署目标环境。
  • 优势:避免分支重复,模块与环境配置统一管理,流程简单高效。

方案二:环境分支+共享模块仓库(适合大型团队)

  • 核心逻辑:每个环境对应独立分支(development/stage/production),模块代码抽离至单独的GitHub仓库,通过Terraform模块引用的方式引入到各环境分支。
  • 分支策略:
    • 模块仓库采用语义化版本管理(如v1.0.0),各环境分支按需引用指定版本的模块。
    • 模块变更先在development分支测试验证,确认无误后升级模块版本,再同步到stage和production分支。
  • 优势:环境边界清晰,每个分支仅包含当前环境的配置,避免误修改其他环境;模块版本可控,适合多团队协作场景。

3. 正确的CI/CD pipeline阶段应如何设置?

以GitHub Actions为例,无论采用哪种分支方案,Pipeline都需包含以下核心阶段:

通用基础阶段(所有环境通用)

  • 代码校验:
    • 执行terraform fmt -check检查代码格式是否规范。
    • 执行terraform validate验证Terraform配置的语法正确性。
  • 初始化与计划:
    • 执行terraform init初始化工作目录,下载模块和提供者插件。
    • 执行terraform plan -out=tfplan生成执行计划并保存,用于后续审核或应用。
  • 应用部署:仅在触发条件满足且审核通过后,执行terraform apply tfplan完成部署。

分环境触发与审核规则

  • Development环境:
    • 触发条件:development分支推送(或单分支方案下development目录代码变更)。
    • 可跳过人工审核,自动执行apply(开发环境风险低,快速迭代需求优先)。
  • Stage环境:
    • 触发条件:stage分支推送(或单分支方案下stage目录代码变更),或main分支合并后自动触发。
    • 需添加人工审核步骤(如GitHub环境审批),确认后再执行apply。
  • Production环境:
    • 触发条件:production分支推送(或单分支方案下production目录代码变更),或从stage分支合并后触发。
    • 必须添加多重审核(如至少2名团队成员审批),且执行plan后需留存执行计划日志,方便事后审计。

示例GitHub Actions配置片段(单分支方案)

name: Terraform Multi-Env Deployment

on:
  push:
    paths:
      - 'modules/**'
      - 'development/**'
      - 'stage/**'
      - 'production/**'

jobs:
  deploy-development:
    runs-on: ubuntu-latest
    if: contains(github.event.head_commit.message, 'deploy: development') || (github.ref == 'refs/heads/main' && contains(github.event.head_commit.modified, 'development/'))
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - name: Terraform Init
        working-directory: ./development
        run: terraform init
      - name: Terraform Validate
        working-directory: ./development
        run: terraform validate
      - name: Terraform Plan
        working-directory: ./development
        run: terraform plan -out=tfplan
      - name: Terraform Apply
        working-directory: ./development
        run: terraform apply tfplan
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_DEV_ACCESS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_DEV_SECRET_KEY }}

  deploy-stage:
    runs-on: ubuntu-latest
    needs: deploy-development
    environment: staging
    if: contains(github.event.head_commit.message, 'deploy: stage') || (github.ref == 'refs/heads/main' && contains(github.event.head_commit.modified, 'stage/'))
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - name: Terraform Init
        working-directory: ./stage
        run: terraform init
      - name: Terraform Validate
        working-directory: ./stage
        run: terraform validate
      - name: Terraform Plan
        working-directory: ./stage
        run: terraform plan -out=tfplan
      - name: Terraform Apply
        working-directory: ./stage
        run: terraform apply tfplan
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_STAGE_ACCESS_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_STAGE_SECRET_KEY }}

内容的提问来源于stack exchange,提问作者Crerem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:06:04