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

Azure DevOps YAML流水线:Terraform无变更时跳过审批及后续阶段

解决Azure DevOps Terraform流水线无变更时跳过带审批的Apply阶段问题

我之前也碰到过这个头疼的问题——Azure DevOps确实会优先触发关联环境的手动审批,再检查作业/阶段的条件,导致无变更时仍需要人工跳过审批,非常低效。下面是几个经过验证的可行方案:

方案1:阶段级条件控制(最推荐)

核心思路是在Plan阶段输出变更状态变量,然后用阶段级的Condition直接控制整个Apply阶段是否启动,这样当无变更时,Apply阶段根本不会被触发,自然也就不会触发审批。

步骤示例:

  1. 在Plan阶段设置输出变量
    给Plan阶段的作业命名,然后在检查变更的步骤中输出标记变量:

    stage: PlanShared
    jobs:
    - job: PlanJob
      name: PlanJob # 必须设置name才能跨阶段传递输出变量
      steps:
      - task: TerraformTaskV4@4
        inputs:
          provider: 'azurerm'
          command: 'plan'
          workingDirectory: '$(System.DefaultWorkingDirectory)/shared'
          commandOptions: '-out=tfplan -detailed-exitcode'
      - bash: |
          exit_code=$?
          # Terraform plan的退出码:0=无变更,2=有变更,其他=失败
          if [ $exit_code -eq 2 ]; then
            echo "##vso[task.setvariable variable=hasSharedChanges;isOutput=true;]yes"
          elif [ $exit_code -eq 0 ]; then
            echo "##vso[task.setvariable variable=hasSharedChanges;isOutput=true;]no"
          else
            echo "Terraform plan执行失败,退出码:$exit_code"
            exit $exit_code
          fi
        name: CheckChanges
        condition: succeeded()
    
  2. 在Apply阶段添加阶段级Condition
    直接用Plan阶段的输出变量控制整个阶段是否运行:

    stage: ApplyShared
    dependsOn: PlanShared
    # 只有当Plan阶段检测到变更时,才启动本阶段
    condition: eq(dependencies.PlanShared.outputs['PlanJob.CheckChanges.hasSharedChanges'], 'yes')
    jobs:
    - deployment: ApplyShared
      displayName: 'Apply - shared'
      environment: 'infra-shared' # 这里的手动审批只会在阶段启动时触发
      strategy:
        runOnce:
          deploy:
            steps:
            - task: TerraformTaskV4@4
              inputs:
                provider: 'azurerm'
                command: 'apply'
                workingDirectory: '$(System.DefaultWorkingDirectory)/shared'
                commandOptions: 'tfplan'
    

这个方案的优势是逻辑清晰,完全避免了不必要的审批触发,是官方推荐的最佳实践。

方案2:用环境Gate自动检查变更

如果不想修改流水线YAML,可以给目标环境添加入口Gate,让系统自动检查是否有变更,无变更时自动拒绝部署:

  • 进入Azure DevOps的「环境」页面,找到infra-shared环境
  • 添加一个「运行脚本」类型的Gate,配置脚本下载TerraformBuild工件,检查.shared-changes文件是否存在
  • 如果文件不存在(无变更),脚本返回非零退出码,Gate自动失败,部署被终止,无需人工干预

这个方案适合需要在环境层面统一管控的场景,但灵活性不如方案1。

方案3:拆分作业流程(临时过渡方案)

如果你暂时无法调整阶段结构,可以拆分Apply阶段的作业:

  1. 先执行一个检查变更的作业,设置变量
  2. 部署作业依赖检查作业,同时添加作业级Condition,并且将环境审批移到作业的Gate中(而不是直接关联环境)

不过这个方案不如方案1简洁,仅作为临时过渡使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:32:35