azure-devopsazure-pipelinesazure-pipelines-build-task

How to use matrix variable within pool demands?


For an Azure Pipelines yaml file I want to run a set of tasks once on every agent in a certain pool. When I looked at jobs strategy matrix, it looked as a good solution for this, but it currently cannot pick-up the variable I use for this.

The pipeline yaml file, relevant for this problem is this part:

resources:
- repo: self

trigger: none

jobs:
- job: RunOnEveryAgent
  strategy:
    maxParallel: 3
    matrix:
      agent_1:
        agentName: Hosted Agent
      agent_2:
        agentName: Hosted VS2017 2
      agent_3:
        agentName: Hosted VS2017 3
  pool:
    name: Hosted VS2017
    demands:
    - msbuild
    - visualstudio
    - Agent.Name -equals $(agentName)

  steps:
  - (etc.)

With this script I tried to setup a matrix to run once on each of the three agents in the pool. However when I try to reference the agent on the list of demands it doesn't pick it up. The actual error message is as follows:

[Error 1] No agent found in pool Hosted VS2017 which satisfies the specified demands:

msbuild

visualstudio

Agent.Name -equals $(agentName)

Agent.Version -gtVersion 2.141.1

If I hardcode the agent name it does work:

    demands:
    - msbuild
    - visualstudio
    - Agent.Name Hosted VS2017 3

Is it supported to use these variables in the pool demands? Or should I use a different variable or expression?


Solution

  • Variables are not supported in some of these jobs, due to the order in which they get expanded.

    What you can do however, is to use template include syntax (https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops) for your job strategy and pass the agentname in as a parameter.

    So your build job in its own YAML file might look like:

    parameters:
      agentName1: ''
      agentName2: ''
      agentName3: ''
    
    jobs:
    - job: RunOnEveryAgent
      strategy:
        maxParallel: 3
        matrix:
          agent_1:
            agentName: ${{ parameters.agentName1 }}
          agent_2:
            agentName: ${{ parameters.agentName2 }}
          agent_3:
            agentName: ${{ parameters.agentName3 }}
      pool:
        name: Hosted VS2017
        demands:
        - msbuild
        - visualstudio
        - Agent.Name -equals ${{ parameters.agentName3 }}
    
      steps:
    

    Your main azure-pipelines.yml then changes to look like this:

    resources:
    - repo: self
    
    trigger: none
    
    jobs:
      - template: buildjob.yml
        parameters:
          agentName1: 'Hosted Agent'
          agentName2: 'Hosted VS2017 2'
          agentName3: 'Hosted VS2017 3'