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

GitHub Enterprise 3.6.2中如何关联Terraform Plan与Apply工作流?

解决GitHub Actions中Terraform Plan与Apply的衔接问题

方案一:分两个工作流,通过GitHub Artifacts传递Plan文件

这是最直接可行的方案,利用GitHub Artifacts在PR触发的Plan工作流和合并触发的Apply工作流之间传递Plan输出文件。

1. PR触发的Plan工作流(.github/workflows/terraform-plan.yml)

name: Terraform Plan

on:
  pull_request:
    paths:
      - '**.tf'
      - '**.tfvars'
      - 'terraform.lock.hcl'

jobs:
  plan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
      actions: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.5.0 # 匹配你的Terraform版本

      - name: Terraform Init
        run: terraform init -backend-config=backend.tfvars # 根据实际配置调整

      - name: Terraform Lint
        run: tflint --config .tflint.hcl # 需提前安装tflint,或使用官方action

      - name: Generate Terraform Plan
        run: |
          terraform plan -out=tfplan.binary
          terraform show -json tfplan.binary > tfplan.json

      - name: Upload Plan Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: tfplan-pr-${{ github.event.number }}
          path: |
            tfplan.binary
            tfplan.json
          retention-days: 30 # 按需调整保留时间

      - name: Add Plan Summary to PR
        uses: actions/github-script@v6
        with:
          script: |
            const fs = require('fs');
            const plan = JSON.parse(fs.readFileSync('tfplan.json', 'utf8'));
            const changes = plan.resource_changes.map(rc => `${rc.type}.${rc.name}: ${rc.change.actions.join(', ')}`);
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `### Terraform Plan Summary\n\`\`\`\n${changes.join('\n')}\n\`\`\``
            });

2. 合并触发的Apply工作流(.github/workflows/terraform-apply.yml)

name: Terraform Apply

on:
  pull_request_target:
    types: [closed]
    paths:
      - '**.tf'
      - '**.tfvars'
      - 'terraform.lock.hcl'

jobs:
  apply:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      actions: read
    if: github.event.pull_request.merged == true
    steps:
      - name: Get PR Number
        id: get-pr
        run: echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT

      - name: Download Plan Artifacts
        uses: actions/download-artifact@v4
        with:
          name: tfplan-pr-${{ steps.get-pr.outputs.pr_number }}
          path: ./plan

      - name: Checkout Merged Code
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.merge_commit_sha }}

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.5.0

      - name: Terraform Init
        run: terraform init -backend-config=backend.tfvars

      - name: Verify Plan Consistency
        run: |
          # 可选:验证当前代码与Plan时的代码一致,防止中间变更
          terraform plan -out=current_plan.binary
          if diff ./plan/tfplan.binary current_plan.binary; then
            echo "代码与Plan版本一致,继续执行Apply"
          else
            echo "警告:当前代码与Plan时的代码存在差异,请确认后再执行"
            # 若需严格校验,可在此处添加exit 1终止工作流
          fi

      - name: Terraform Apply
        run: terraform apply ./plan/tfplan.binary
        env:
          TF_IN_AUTOMATION: "true"

关键细节说明

  • Artifact命名包含PR号,确保合并时能精准匹配对应的Plan文件
  • 使用pull_request_target触发合并事件,避免私有仓库的权限访问问题
  • 可选的一致性检查步骤,防止PR合并后到Apply前有其他代码变更
  • 配置必要的工作流权限,确保能读写PR评论、操作Artifacts

方案二:利用GitHub Environments实现审批(需手动触发)

如果坚持要在同一工作流中完成,可借助GitHub Environments的手动审批功能,但无法自动等待PR合并,只能在Plan后暂停等待人工触发Apply(适合需要额外审核的场景)。

示例工作流:

name: Terraform Plan & Apply

on:
  pull_request:
    paths:
      - '**.tf'

jobs:
  plan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      actions: write
    steps:
      # 同方案一的Plan步骤,省略...
      - name: Upload Plan Artifact
        uses: actions/upload-artifact@v4
        with:
          name: tfplan
          path: tfplan.binary

  apply:
    needs: plan
    runs-on: ubuntu-latest
    environment: production # 提前在仓库设置该环境并开启审批
    if: github.event.pull_request.merged == true
    permissions:
      contents: read
      actions: read
    steps:
      - name: Download Plan Artifact
        uses: actions/download-artifact@v4
        with:
          name: tfplan
      # 同方案一的Apply步骤,省略...

注意事项

  • 工作流最长执行时间为72小时,若PR审核超过这个时间,工作流会直接失败
  • 需手动在GitHub Environments中批准apply任务,无法完全自动触发,因此更适合需要额外人工确认的场景

总结

推荐使用方案一,它完美适配"PR创建自动Plan,合并自动Apply"的需求,避免了工作流长时间挂起的问题,同时通过Artifacts保证了Plan文件的可靠传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:25:44