12
votes

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?

2

2 Answers

3
votes

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://docs.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'
4
votes
parameters:
  - name: agentNames
    type: object
    default: []
jobs:
- job: RunOnEveryAgent
  strategy:
    matrix:
       ${{ each agentName in parameters.agentNames }}:
        ${{ agentName }}:
         agentName: ${{ agentName }}
  pool:
    name: Hosted VS2017
    demands:
    - msbuild
    - visualstudio
    - Agent.Name -equals $(agentName)

This would be a better solution in case you want to add more agents in future