The one thing I haven't seen fully clarified is that while this isn't possible at the "pipeline" level (ie set it once globally) because parameters are a runtime scoped thing and setting pool:
at the pipeline level isn't able to wait for the runtime parameters, BUT you can still EASILY override the agent per stage, job, or step.
To do it in a straightforward and consistent fashion, you can use a templated stage/job/step that accepts the agentPool as a parameter (but only the vmImage:
portion), then you can use a YAML conditional to detect whether it is one of the valid Azure DevOps managed agents windows-latest
/ubuntu-latest
/macos-latest
/etc with the few specific versions, IF NOT then you can assume it is a self hosted pool and use that as the name:
attribute of pool:
vs vmImage:
.
Thanks to Vito, Marius and GY for their helpful examples.
azure-pipelines.yml
parameters:
- name: agentPool
type: string
default: windows-latest
# Valid Azure images: https://github.com/actions/runner-images#available-images
values:
- selfHosted1
- selfHosted2
- windows-latest
- windows-2019
- macos-latest
- ubuntu-latest
stages:
- template: azure-deploy.yml
parameters:
agentPool: ${{ parameters.agentPool }}
azure-deploy.yml
parameters:
- name: agentPool
type: string
default: windows-latest
stages:
- stage: Deploy
displayName: Deploy Bicep
pool:
${{ if or(or(startsWith(parameters.agentPool, 'windows'), startsWith(parameters.agentPool, 'macos')), startsWith(parameters.agentPool, 'ubuntu')) }}:
vmImage: ${{ parameters.agentPool }}
${{ if not(or(or(startsWith(parameters.agentPool, 'windows'), startsWith(parameters.agentPool, 'macos')), startsWith(parameters.agentPool, 'ubuntu'))) }}:
name: ${{ parameters.agentPool }}
jobs: <snipped to avoid too much boilerplate>