Home > Enterprise >  Azure Pipelines and docker containers: How to use runtime parameters to choose a container at runtim
Azure Pipelines and docker containers: How to use runtime parameters to choose a container at runtim

Time:10-08

I am running an Azure pipeline inside a Docker container on a Microsoft-hosted agent. The container is specified in the beginning of my YAML file:

pool:
  vmImage: ubuntu-latest

container: 
  image: mycompany.jfrog.io/xyz-docker-local/myimage:debian10
  options: --privileged
  endpoint: AzureToArtifactory

steps:
- script: |
    [...]

Result: works fine

I have defined a second container, called myimage:ubuntu22. I want to use a runtime parameter to choose between the Debian container and the Ubuntu container. But I cannot figure out the correct syntax for switching between containers.

First try at switching:

Having no luck finding the syntax in the official Microsoft docs or elsewhere, I chose a syntax similar to what I have done with other resources.

parameters:
- name: BuildArchitecture
  type: string
  default: 'x64 ubuntu 22'
  values:
  - 'x64 ubuntu 22'
  - 'x64 debian 10'

pool:
  vmImage: ubuntu-latest

container: 
  ${{ if eq(parameters.buildArchitecture, 'x64 ubuntu 22') }}:
    image: mycompany.jfrog.io/xyz-docker-local/myimage:ubuntu22
    options: --privileged
    endpoint: AzureToArtifactory
  ${{ else }}:
    image: mycompany.jfrog.io/xyz-docker-local/myimage:debian-10
    options: --privileged
    endpoint: AzureToArtifactory

steps:
[...]

Result: "A template expression is not allowed in this context."

Second try:

Maybe the indentation was the problem.

[...]
container: 
${{ if eq(parameters.buildArchitecture, 'x64 ubuntu 22') }}:
  image: mycompany.jfrog.io/xyz-docker-local/myimage:ubuntu22
  options: --privileged
  endpoint: AzureToArtifactory
${{ else }}:
  image: mycompany.jfrog.io/xyz-docker-local/myimage:debian-10
  options: --privileged
  endpoint: AzureToArtifactory
[...]

Result: "A template expression is not allowed in this context."

Third try:

Not indentation. Maybe it needs - at the beginning of each conditional expression.

[...]
container:
- ${{ if eq(parameters.buildArchitecture, 'x64 ubuntu 22') }}:
  image: mycompany.jfrog.io/xyz-docker-local/myimage:ubuntu22
  options: --privileged
  endpoint: AzureToArtifactory
- ${{ else }}:
  image: mycompany.jfrog.io/xyz-docker-local/myimage:debian-10
  options: --privileged
  endpoint: AzureToArtifactory
[...]

Result: "A sequence was not expected."

Fourth try:

I thought that perhaps I needed to define the containers as resources. So I created the container resources, and verified that the pipeline works when I select the resources individually, without any selection logic. Then I added the logic back in:

[...]
resources:
  containers:
  - container: ubuntu
    image: mycompany.jfrog.io/xyz-docker-local/myimage:ubuntu22
    options: --privileged
    endpoint: AzureToArtifactory
  - container: debian
    image: mycompany.jfrog.io/xyz-docker-local/myimage:debian-10
    options: --privileged
    endpoint: AzureToArtifactory

${{ if eq(parameters.buildArchitecture, 'x64 ubuntu 22') }}:
  container: ubuntu
${{ else }}:
  container: debian
[...]

Result: we're back to "A template expression is not allowed in this context."

Fifth try

Maybe I should skip the conditional logic and turn the container tag into a variable.

[...]
variables:
  - name: dockerTag
    ${{ if eq(parameters.buildArchitecture, 'x64 ubuntu 22') }}:
      value: 'ubuntu22'
    ${{ else }}:
      value: 'debian-10'

container: ubuntu
  image: mycompany.jfrog.io/xyz-docker-local/myimage:${{ variables.dockerTag }}
  options: --privileged
  endpoint: AzureToArtifactory

steps:
[...]

Result: "Mapping values are not allowed in this context.", referring to the container.image line.

Question:

What is the correct procedure or syntax for choosing between Docker containers at runtime?

CodePudding user response:

What is the correct procedure or syntax for choosing between Docker containers at runtime?

To use the If expression and parameters to set the container image, you need to define the container at Job level.

For example:

parameters:
- name: BuildArchitecture
  type: string
  default: 'x64 ubuntu 22'
  values:
  - 'x64 ubuntu 22'
  - 'x64 debian 10'

pool:
  vmImage: ubuntu-latest

jobs:
  - job:  job1
    container:
     ${{ if eq(parameters.buildArchitecture, 'x64 ubuntu 22') }}:
       image:  mycompany.jfrog.io/xyz-docker-local/myimage:ubuntu22
       options: --privileged
       endpoint: AzureToArtifactory
     ${{ else }}:
       image: mycompany.jfrog.io/xyz-docker-local/myimage:debian-10
       options: --privileged
       endpoint: AzureToArtifactory
    steps:
      - script: echo "1"
  • Related