Azure 管道:在多阶段参数化中使用输出变量

Aure pipeline : use output variable in multi-stage parametrised

我遇到了无法解决的问题。

关于 this documentation 似乎可以在第一阶段将变量设置为作业的输出,然后将其用作输入以在第二阶段设置作业变量。

我面临的 pbm 是我的阶段是参数化的,所以它们的名字不是常数。

这里是我的示例代码:

name: mypipeline

parameters:
  - name: Application
    displayName: Application to deploy the front end using front door
    type: string
  - name: stage_vars
    displayName: stage VARS
    type: object
    default:
    - stage_1
    - stage_2
    - none
trigger: none

stages:
  - stage: Build
    displayName: ${{ parameters.Application }} - Build.
    pool:
      name: Azure Pipelines
      vmImage: windows-2019
    jobs:
    - template: ../templates/job_BuildAndPublish.yml
      parameters:
        BuildId:  $(Build.BuildId)
        importTerratest: false
        importARM: true

  - ${{ each stageregion in parameters.stage_vars }}:
    - ${{ if ne(stageregion, 'none') }}:
        - template: ../templates/isolated_web/tf_plan_stage.yml
          parameters:
            BuildId: $(system.BuildId)
            Predecessors: 'Build'

        - template: ../templates/isolated_web/tf_apply_stage.yml
          parameters:
            Predecessors: '${{stageregion}}_prepare'

构建模板没有用,但来自 tf_plan_stage 和 tf_apply_stage 的模板如下:

tf_plan_stage.yml :

parameters:
  - name: BuildId
    type: string
    default: $(system.BuildId)
  - name: stage
    type: string
    default: Deploy_prepare
  - name: Predecessors
    type: string
    default: none
stages:
  - stage: ${{ parameters.stage }}
    ? ${{ if and(ne(parameters.Predecessors, 'previous'), ne(parameters.Predecessors, 'none') ) }}
    : dependsOn: ${{parameters.Predecessors}}
    displayName: ${{ parameters.TF_VAR_STAGE }} Terraform plan & publish artifact for ${{ parameters.TF_VAR_APPLICATION }}
    pool:
      name: Azure Pipelines
      vmImage: windows-2019
    jobs:
    - deployment: PreDeployTerraform
      displayName: ${{ parameters.TF_VAR_STAGE }} Terraform plan & publish artifact     
      environment: PLAN_${{ parameters.TF_VAR_ENVIRONMENT }}
      timeoutInMinutes: 480
      strategy:
        runOnce:
          deploy:
            steps:
            - checkout: none
            # set output planAttempt output available for later Apply job
            - powershell: | 
                echo "jobAttempt is $(System.JobAttempt)"
                echo "##vso[task.setvariable variable=planAttempt;isOutput=true;]$(System.JobAttempt)"
              name: setVarJobAttempt
            - powershell: | 
                echo "variable setVarJobAttempt.planAttempt value is : $(setVarJobAttempt.planAttempt)"
              name: getplanAttemptVar

tf_apply_stage.yml :

    parameters:
  - name: stage
    type: string
    default: Deploy_prepare
  - name: Predecessors
    type: string
    default: none
stages:
  - stage: ${{ parameters.stage }}
    ? ${{ if and(ne(parameters.Predecessors, 'previous'), ne(parameters.Predecessors, 'none') ) }}
    : dependsOn: ${{parameters.Predecessors}}
    displayName: ${{ parameters.TF_VAR_STAGE }} download artifact & Terraform apply changes to ${{ parameters.TF_VAR_APPLICATION }}
    pool:
      name: Azure Pipelines
      vmImage: windows-2019
    jobs:
    - deployment: DeployTerraform
      displayName: ${{ parameters.TF_VAR_STAGE }} download artifact & Terraform apply changes
      variables:
        # this one fails in pipeline : "[not recognise"
        planJobAttempt: $[ stageDependencies.[parameters.Predecessors].PreDeployTerraform.outputs['setVarJobAttempt.planAttempt'] ]
        # this one runs with no result in pipeline : planJobAttempt is the string "stageDependencies['parameters.Predecessors'].PreDeployTerraform.outputs['setVarJobAttempt.planAttempt']"
        # planJobAttempt: $[ stageDependencies['parameters.Predecessors'].PreDeployTerraform.outputs['setVarJobAttempt.planAttempt'] ]
      environment: ${{ parameters.TF_VAR_ENVIRONMENT }}
      timeoutInMinutes: 480
      strategy:
        runOnce:
          deploy:
            steps:
              - checkout: none
              
              - powershell: | 
                  echo "jobAttempts outputs are :  $[ stageDependencies.[parameters.Predecessors].PreDeployTerraform.outputs ]"

              - powershell: | 
                  echo "jobAttempt is $[ stageDependencies['parameters.Predecessors'].PreDeployTerraform.outputs['setVarJobAttempt.planAttempt'] ]"

              - powershell: | 
                  echo "plan file for terraform is : $(pipeline_artifact_folder_download)/$(planJobAttempt)_${{ parameters.Predecessors }}/$(artefact_terraform_plan)_${{ parameters.TF_VAR_STAGE }}"

我尝试了不同的方法让我的 system.jobAttempts 从 tf_plan_stage 阶段到 tf_apply_stage 阶段,但没有成功,因为最后一个阶段的变量(tf_apply ) 接缝无法从“参数化”舞台名称中找到值。

有办法吗?

感谢您的任何回答。

好的,

我再一次回答我自己的问题:D

我终于找到了在我的变量声明中使用 parameters.Predecessors 值的方法。 其次,Microsoft 文档接缝不会更新。

tf_apply_stage.yml应该是下面这样的;

  parameters:
  - name: stage
    type: string
    default: Deploy_prepare
  - name: Predecessors
    type: string
    default: none
stages:
  - stage: ${{ parameters.stage }}
    ? ${{ if and(ne(parameters.Predecessors, 'previous'), ne(parameters.Predecessors, 'none') ) }}
    : dependsOn: ${{parameters.Predecessors}}
    displayName: ${{ parameters.TF_VAR_STAGE }} download artifact & Terraform apply changes to ${{ parameters.TF_VAR_APPLICATION }}
    pool:
      name: Azure Pipelines
      vmImage: windows-2019
    jobs:
    - deployment: DeployTerraform
      displayName: ${{ parameters.TF_VAR_STAGE }} download artifact & Terraform apply changes
      variables:
        *# this one give he good value for Variable*
        planJobAttempt: $[ stageDependencies.${{ parameters.Predecessors }}.PreDeployTerraform.outputs['PreDeployTerraform.setVarJobAttempt.planAttempt'] ]            
      environment: ${{ parameters.TF_VAR_ENVIRONMENT }}
      timeoutInMinutes: 480
      strategy:
        runOnce:
          deploy:
            steps:
              - checkout: none
              
              - powershell: | 
                  echo "plan file for terraform is : $(pipeline_artifact_folder_download)/$(planJobAttempt)_${{ parameters.Predecessors }}/$(artefact_terraform_plan)_${{ parameters.TF_VAR_STAGE }}"

我在 BOLD 中输入了上面的主要更改:

planJobAttempt: $[ stageDependencies.${{ parameters.Predecessors }}.PreDeployTerraform.outputs['PreDeployTerraform.setVarJobAttempt.planAttempt'] ]

作业名称必须在变量声明中设置两次!

感谢阅读我的文章的人 post ;)

非常感谢来自@Kay07949 的 this post,他给出了很好的答案 ;)