azure-devopsazure-pipelinesazure-devops-services

Resolving Predefined Agent Variables in Runtime Expressions


I have the following scenario, it is simplified for the sake of brevity, but outlines my problem.

I have a 2 Job pipeline.

BreakMatrix Job: A job that runs on an AdminPool and outputs 2 variables with the following names ENV1 and ENV2. The names are important because each of them matches the name of an Environment running in a separate MachinePool VM deployment pool.

Upgrade Job: A deployment job that depends on the BreakMatrix job and that runs on a VM MachinePool, with a tag that will select ENV1 and ENV2 environments.

I am trying to pass in one of the variables to each of the corresponding Environments:

    - job: BreakMatrix
      pool: AdminPool
      steps:
      - checkout: none
      - powershell: |
          $result1 = @{"Hostname" = "Env1Value"}
          $result2 = @{"Hostname" = "Env2Value"}
          Write-Host "##vso[task.setvariable variable=ENV1;isOutput=true;]$result1"
          Write-Host "##vso[task.setvariable variable=ENV2;isOutput=true;]$result2"
        name: outputter

    - deployment: Upgrade
      dependsOn: BreakMatrix
      variables:
        agentName: $(Environment.ResourceName)
        agentName2: $(Agent.Name)
        formatted: $[ format('outputter.{0}', variables['agentName']) ]
        result1: $[ dependencies.BreakMatrix.outputs[format('outputter.{0}', variables['agentName'])] ]
        result2: $[ dependencies.BreakMatrix.outputs[format('outputter.{0}', variables['agentName2'])] ]
        result3: $[ dependencies.BreakMatrix.outputs[format('outputter.{0}', variables['Agent.Name'])] ]
        hardcode: $[ dependencies.BreakMatrix.outputs['outputter.ENV2'] ]
        json: $[ convertToJson(dependencies.BreakMatrix.outputs) ]
      environment:
        name: MachinePool
        resourceType: VirtualMachine
        tags: deploy-dynamic
      strategy:
        rolling:
          preDeploy:
            steps:
              - powershell: |
                  echo 'Predeploy'
                  echo "agentName: $(agentName)"
                  echo "agentName2: $(agentName2)"
                  echo "env: $(Environment.ResourceName)"
                  echo "formatted: $(formatted)"
                  echo "harcode: $(harcode)"
                  echo "result1: $(result1)"
                  echo "result2: $(result2)"
                  echo "result3: $(result3)"
                  echo "json: $(json)"
          deploy:
            steps:
              - powershell: |
                  echo 'Deploy'

Output for ENV2 pre-deploy step:

Predeploy
agentName: ENV2
agentName2: ENV2
env: ENV2
formatted: outputter.ENV2
hardcode: {
Hostname:Env2Value}
result1: 
result2: 
result3: 
json: {
  
outputter.ENV2: 
\"Hostname\":\"Env2Value\"

}

If i try to use a predefined variable in a dependency expression they don't seem to properly resolve, but if i just simply map them to a variable / format them they work. Note: The environment names are actually dynamically calculated before these jobs run so I cannot use parameters or static/compile time variables.

Any suggestions on how to pass in only the relevant variable to each of the environments ?


Solution

  • I got confirmation on the developer community that this is not possible.

    Relevant part:

    But I am afraid that the requirement couldn’t be achieved.

    The reason is that the dependencies.xx.outputs expression can’t read the variable(variables['Agent.Name']) and format expression value defined in the YAML pipeline.

    It now only supports hard-coding the name of the variable to get the corresponding job variable value.