微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Azure DevOps 使用变量作为部署阶段之间的条件

如何解决Azure DevOps 使用变量作为部署阶段之间的条件

我目前通过 Azure DevOps Pipelines 使用 terraform 构建我们所有的 Azure 基础设施。这一直运行良好,我们有一个标准的管道,它调用两个模板

  • 计划阶段
    • 部署工作
    • 规划模板
    • 每次运行
  • 应用阶段
    • 部署工作
    • 应用模板
    • 通过手动审批检查运行

在这工作正常,但我想要做的是只有在需要进行更改时才运行应用步骤。我找到了其他关于如何在计划阶段获取变量集的文章,我可以这样做并且效果很好。

我可以在下一步中调用这个相同的变量

  variables:
    varFromPlanStage: $[stageDependencies.Plan.planning_stage.outputs['planning_stage.terraformPlanResult.terraformChanges']]
  steps:
    - script: echo $(varFromPlanStage)

但是当我尝试在条件中使用相同的变量时,问题就出现了。 我发现你们的方式不同,需要依赖而不是 stagedependancy,但无论我怎么努力,我都无法让它工作。

管道看起来像这样。

stages:
- stage: 'Plan'
  displayName: 'Planning'
  jobs:
  - deployment: planning_stage
    displayName: 'Planning Changes'
    pool:
      vmImage: 'Ubuntu-20.04'
    environment: 'planning'
    strategy:
      runOnce:
        deploy:
          steps:
          - template: /Pipelines/10-TEST-terraform-planning-template.yml  # Run the Planning Template
            parameters:
                terraform_version: ${{ parameters.terraform_version }}
                terraform_backend_service_arm: ${{ parameters.terraform_backend_service_arm }}
                terraform_backend_resource_group: ${{ parameters.terraform_backend_resource_group }}
                terraform_backend_storage_account: ${{ parameters.terraform_backend_storage_account }}
                terraform_backend_storage_container: ${{ parameters.terraform_backend_storage_container }}
                terraform_state_key: ${{ parameters.terraform_state_key }}
                git_working_directory: ${{ parameters.git_working_directory }}

# This is the Build Stage - Only do this when on the master branch (which is via a PR)

- stage: 'Apply'
  condition: and(succeeded(),eq(dependencies.Plan.planning_stage.outputs['planning_stage.terraformPlanResult.terraformChanges'],'true'))
  variables:
    varFromPlanStage: $[stageDependencies.Plan.planning_stage.outputs['planning_stage.terraformPlanResult.terraformChanges']]
  displayName: 'Applying Changes'
  jobs:
  - deployment: applying_stage
    displayName: 'Lets Build'
    pool:
      vmImage: 'Ubuntu-20.04'
    environment: 'building'
    strategy:
      runOnce:
        deploy:
          steps:
            - script: echo $(varFromPlanStage) # Just a test
            - template: /Pipelines/20-TEST-terraform-apply-template.yml  # Run the Apply Template
              parameters:
                  terraform_version: ${{ parameters.terraform_version }}
                  terraform_backend_service_arm: ${{ parameters.terraform_backend_service_arm }}
                  terraform_backend_resource_group: ${{ parameters.terraform_backend_resource_group }}
                  terraform_backend_storage_account: ${{ parameters.terraform_backend_storage_account }}
                  terraform_backend_storage_container: ${{ parameters.terraform_backend_storage_container }}
                  terraform_state_key: ${{ parameters.terraform_state_key }}
                  git_working_directory: ${{ parameters.git_working_directory }}

导出变量的规划模板部分称为 terraformPlanResult,其中 var 为 terraformChanges

知道我在这里做错了什么,为什么我不能将变量称为条件,但我可以作为步骤的一部分?

谢谢!

解决方法

对我有用的(通过许多试验和错误)是格式:

dependencies.stage_name.outputs['job_name.step_name.variable_name']

在您的情况下,这将是:

dependencies.Plan.outputs['planning_stage.terraformPlanResult.terraformChanges']

如果这不起作用,唯一不寻常的是您的 planning_stage 是一个部署。您可以尝试将其更改为常规工作。

这是一个 pipeline that tests various ways of referencing outputs in conditions

,

对我来说,这看起来像是 Azure Devops 上的一个问题(稍后 O 将准备最小的工作示例并为此创建一个错误)。因为相同的语法适用于常规作业,但不适用于部署。您也可以使用 condition: in(dependencies.A.result,'Succeeded','SucceededWithIssues','Skipped') 之类的条件,但不能使用输出。而根据这个

"dependencies": {
  "<STAGE_NAME>" : {
    "result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled","outputs": {
        "jobName.stepName.variableName": "value"
    }
  },"...": {
    // another stage
  }
}

这是正确的语法。

我还检查了 this,但使用生命周期钩子而不是作业名称对我没有帮助。

如果它们处于同一阶段,您可以在作业条件中使用输出变量有什么奇怪的。

Here 是问题的链接。

,

这似乎会有所不同,具体取决于您是在“部署”作业还是“作业”作业中设置变量。经过一些试验、错误和谷歌搜索,我设法为两者工作。下面的例子:-)

  • 从“部署”作业传递变量的示例。
# Example passing variables from a 'deployment' job.
stages:

  # Create some variables to pass to next stage.
 - stage: 'A'
    jobs:
    - deployment: 'A1'
      pool:
        vmImage: 'windows-2019'
      environment: 'test'
      strategy:
        runOnce:
          deploy:
            steps:
            # Create a variable.
            - task: PowerShell@2
              name: foo
              displayName: 'Create a variable.'
              inputs:
                targetType: 'inline'
                script: |
                    echo "##vso[task.setvariable variable=bar;isOutput=true]apple"
            # Check variable.
            - task: PowerShell@2
              displayName: 'Check a variable.'
              inputs:
                targetType: 'inline'
                script: |
                  Write-Host "$env:MY_MAPPED_ENV_VAR"
              env:
                MY_MAPPED_ENV_VAR: $(foo.bar)

  # Confirm condition works & variables are available for use.
 - stage: 'B'
    dependsOn:
    - 'A'
    variables:
      - name: varFromStageA
        # stageDependencies.stageName.deploymentName.outputs['deploymentName.stepName.variableName']
        value: $[ stageDependencies.A.A1.outputs['A1.foo.bar'] ]
    # dependencies.stageName.outputs['deploymentName.deploymentName.stepName.variableName']
    condition: and(succeeded(),eq(dependencies.A.outputs['A1.A1.foo.bar'],'apple'))
    jobs:
    - job: 'B1'
      pool:
        vmImage: 'windows-2019'
      steps:
      # Confirm variable has been passed between stages.
      - task: PowerShell@2
        displayName: 'Confirm var passed between stages'
        inputs:
          targetType: 'inline'
          script: |
            Write-Host "$env:MY_MAPPED_ENV_VAR"
        env:
          MY_MAPPED_ENV_VAR: $(varFromStageA)
  • 从“作业”作业传递变量的示例。
# Example passing variables from a 'job' job.
stages:

  # Create some variables to pass to next stage.
  - stage: 'A'
    jobs:
    - job: 'A1'
      pool:
        vmImage: 'windows-2019'
      steps:
      # Create a variable.
      - task: PowerShell@2
        name: foo
        displayName: 'Create a variable.'
        inputs:
          targetType: 'inline'
          script: |
              echo "##vso[task.setvariable variable=bar;isOutput=true]apple"
      # Check variable.
      - task: PowerShell@2
        displayName: 'Check a variable.'
        inputs:
          targetType: 'inline'
          script: |
            Write-Host "$env:MY_MAPPED_ENV_VAR"
        env:
          MY_MAPPED_ENV_VAR: $(foo.bar)

  # Confirm condition works & variables are available for use.
  - stage: 'B'
    dependsOn:
    - 'A'
    variables:
      - name: varFromStageA
        # stageDependencies.stageName.jobName.outputs['stepName.variableName']
        value: $[ stageDependencies.A.A1.outputs['foo.bar'] ]
    # dependencies.stageName.outputs['jobName.stepName.variableName']
    condition: and(succeeded(),eq(dependencies.A.outputs['A1.foo.bar'],'apple'))
    jobs:
    - job: 'B1'
      pool:
        vmImage: 'windows-2019'
      steps:
      # Confirm variable has been passed between stages.
      - task: PowerShell@2
        displayName: 'Confirm var passed between stages'
        inputs:
          targetType: 'inline'
          script: |
            Write-Host "$env:MY_MAPPED_ENV_VAR"
        env:
          MY_MAPPED_ENV_VAR: $(varFromStageA)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?