user2382684
user2382684

Reputation: 155

Execute Azure Devops job on a pool based on conditional parameter

I am trying to execute an Azure Devops Job on a specific pool based on a condition. The goal is to switch between self-hosted agent and microsoft agent. Here is the configuration:

parameters:
  custom_agent: true

jobs:
  - job: Test
    displayName: Test job
  - ${{ if eq(parameters.custom_agent, true) }}:
    - pool:
      name: mypool
      demands:
        - agent.os -equals Linux
  - ${{ if eq(parameters.custom_agent, false) }}:
    - pool:
        vmImage: 'ubuntu-latest'
    steps:
      - task: npmAuthenticate@0

enter image description here

Any ideas ?

Upvotes: 10

Views: 11089

Answers (5)

dragon788
dragon788

Reputation: 3931

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>

Upvotes: 0

Marius
Marius

Reputation: 129

The below example solved my requirement

parameters:
  - name: 'vmImage'
    type: string
    default: 'ubuntu-latest'
  - name: 'agentPool'
    type: string
    default: ''

jobs:
  - job: 'Example'
    pool:
      ${{ if ne(parameters.agentPool, '') }}:
        name: ${{ parameters.agentPool }}
      ${{ if eq(parameters.agentPool, '') }}:
        vmImage: ${{ parameters.vmImage }}
    steps:
      - script: example

Upvotes: 10

GY_
GY_

Reputation: 418

Another apporach to conditionally select pools if you use non-vm pools:

variables:
- ${{ if eq(parameters.custom_agent, true) }}:
  - name: testJobPool
    value: mypool
- ${{ if eq(parameters.custom_agent, false) }}:
  - name: testJobPool
    value: mypool_second

jobs:
- job: Test
  displayName: Test job
  pool:
    name: $(testJobPool)
  steps:
    - task: npmAuthenticate@0

This has proved working.

Upvotes: 5

Vito Liu
Vito Liu

Reputation: 8308

We can specify conditions under which a step, job, or stage will run. We can configure the jobs in the pipeline with different condition entries, and set demands based on those conditions.

A skeleton version looks like this:

parameters:
- name: custom_agent
  displayName: Pool Image
  type: boolean
  default: True

jobs:
  - job: selfhostedagent
    condition: eq(${{ parameters.custom_agent }}, True)
    displayName: 'self_hosted agent'
    pool:
      name: Default
      demands:
        - Agent.Name -equals WS-VITOL-01
    steps:
      - script: echo self_hosted agent

  - job: hostedagent
    condition: eq(${{ parameters.custom_agent }}, False)
    displayName: 'hosted agent'
    pool:
      vmImage: 'ubuntu-latest'
      
    steps:
      - script: echo hosted agent

Update1

In addition, we can configure task template, then use the template in the steps.

Result:

enter image description here

Upvotes: 5

DreadedFrost
DreadedFrost

Reputation: 2998

It looks like pool is not a valid property of a job type

Try switching your job to a deployment type:

jobs:

  - deployment: Test
  - ${{ if eq(parameters.custom_agent, true) }}:
     pool:
      name: mypool
      demands:
        agent.os -equals Linux
    strategy:
        runOnce:    
          deploy:
            steps:

Upvotes: -2

Related Questions