Passing variables in Azure Pipelines YAML tasks, jobs and stages.

Tzahi Kolber
7 min readAug 22, 2024

--

recently I found it very useful to get a variable in one task, job or even a stage, and pass them on to the next step in the Yaml file in Azure DevOps.

There are many examples out there, but still, I didn’t find a good simple Yaml with explanations, of all the important fields of it.

In this blog, I will provide 3 basic examples of passing variables between tasks, jobs and stages, with a very simple explanation for each one of the major parts involved.

Just before we start, I would like to add a list of the best links related to variables, conditions and expressions in Yamls:

Passing variables between tasks in the same job

In this example we will get a variable (VM name in this case) at the first task and pass it through to the next task:

  1. At the first step named vstat, I will get a list of all the virtual machines (VMs) by names and save them to a vibrable named vmnameselected.
  2. Afterwords, I will save the vmnameselected to an “output variable” inside the Yaml called vmname.
    This output variable (vmname) will be used in the next task.
  • Please notice to the format of the variable's settings!
    In this example, when we pass a variable from task to task, the syntax will be as the following:
echo "##vso[task.setvariable variable=output-vibrable]$original-vibrable"

Examples:

  1. At the first example, the 2 conditions MUST meet:
condition: and(succeeded(), contains(variables['vmname'], 'vm1'))

A. The previous task was succeeded
&
B. The variables contains VM1

trigger: none

jobs:
- job: Variabletest
steps:
- task: AzureCLI@2
name: vstat
displayName: Get VM name variables
inputs:
connectedServiceNameARM: "DEMOSA"
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
$vmnameselected = (az vm list | ConvertFrom-Json).name
echo "##vso[task.setvariable variable=vmname]$vmnameselected"
echo "variable vmname is $vmnameselected"

- task: AzureCLI@2
displayName: dependency by variable
condition: and(succeeded(), contains(variables['vmname'], 'vm1'))
inputs:
azureSubscription: 'DEMOSA'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
Write-Host "##[warning] listing resource groups"
(az group list | ConvertFrom-Json).name

The variables as we can see contain VM1 & VM2

Since BOTHS 2 contentions met, the second task (dependency by vibrable) was executed.

2. At the second example, there are 2 different conditions that MUST meet:

condition: and(succeeded(), not(contains(variables['vmname'], 'vm1')))

A. The previous task was succeeded
&
B. The variables should NOT contain VM1

trigger: none

jobs:
- job: Variabletest
steps:
- task: AzureCLI@2
name: vstat
displayName: Get VM name variables
inputs:
connectedServiceNameARM: "DEMOSA"
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
$vmnameselected = (az vm list | ConvertFrom-Json).name
echo "##vso[task.setvariable variable=vmname]$vmnameselected"
echo "variable vmname is $vmnameselected"

- task: AzureCLI@2
displayName: dependency by variable
condition: and(succeeded(), not(contains(variables['vmname'], 'vm1')))
inputs:
azureSubscription: 'DEMOSA'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
Write-Host "##[warning] listing resource groups"
(az group list | ConvertFrom-Json).name

The variables as we can see contain VM1 & VM2

Since only 1 condition was met, the second task (dependency by vibrable) was skipped.

condition: and(succeeded(), ne(variables[‘vmname’], ‘vm1’))
In case the previous task was succeeded AND the output vibrable NOT equals to vm1

condition: and(succeeded(), eq(variables[‘vmname’], ‘vm1’))
In case the previous task was succeeded AND the output vibrable equals to vm1

Passing variables between jobs in the same YAML

In this example we will get a variable (VM name in this case) at the first job and pass it through to other job in the same YAML:

  1. At the first job named GettingVariable, I will get a list of all the virtual machines (VMs) by names and save them to a vibrable named vmnameselected.
  2. Afterwords, I will save the vmnameselected to an “output variable” inside the Yaml called vmname.
    This output variable (vmname) will be used in the next job.
  • Please notice to the format of the variable’s settings!
    In this example, when we pass a variable from one job to another job, the syntax will be as:
echo "##vso[task.setvariable variable=vmname;isOutput=true]$vmnameselected"
  • Also please notice that the condition syntax was changed:

Syntax: and(succeeded(), eq(dependencies.<job-name>.outputs['<step-name>.<variable-name>'], 'true'))

Examples:

  1. At the first example, the 2 conditions MUST meet:
condition: and(succeeded(), contains(dependencies.GettingVariable.outputs['vstat.vmname'], 'vm1'))

A. The previous job was succeeded
&
B. The variables contain VM1

  • Notice that the condition’s syntax, between jobs and tasks are DIFFERENT!
trigger: none

jobs:
- job: GettingVariable
steps:
- task: AzureCLI@2
name: vstat
displayName: Get VM name variables
inputs:
connectedServiceNameARM: "DEMOSA"
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
$vmnameselected = (az vm list | ConvertFrom-Json).name
echo "##vso[task.setvariable variable=vmname;isOutput=true]$vmnameselected"
echo "variable vmname is $vmnameselected"

- job: TestVariable
dependsOn: GettingVariable
condition: and(succeeded(), contains(dependencies.GettingVariable.outputs['vstat.vmname'], 'vm1'))
steps:
- task: AzureCLI@2
displayName: dependency by variable
inputs:
azureSubscription: 'DEMOSA'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
Write-Host "##[warning] listing resource groups"
(az group list | ConvertFrom-Json).name

The variables as we can see contain VM1 & VM2

Since BOTHS 2 contentions met, the second job (dependency by vibrable) was executed.

2. At the second example, there are 2 different conditions that MUST meet:

    condition: and(succeeded(), not(contains(dependencies.GettingVariable.outputs['stat.vmname'], 'vm1')))

A. The previous task was succeeded
&
B. The variables should NOT contain VM1

Since only 1 contention was met, the second task (dependency by vibrable) was skipped.

Passing variables between stages in the same YAML

In this example we will get a variable (VM name in this case) at the first stage and pass it through to other stage in the same YAML:

  1. At the first stage named stg1, I will get a list of all the virtual machines (VMs) by names and save them to a vibrable named vmnameselected.
  2. Afterwords, I will save the vmnameselected to an “output variable” inside the Yaml called vmname.
    This output variable (vmname) will be used in the next stage.
  • Please notice to the format of the variable’s settings!
    In this example, when we pass a variable from step to step, the syntax will be the same as job to job:
echo "##vso[task.setvariable variable=vmname;isOutput=true]$vmnameselected"
  • Please notice that the condition syntax was changed:
  • Syntax: and(succeeded(), eq(stageDependencies.<stage-name>.outputs['<job-name>.<step-name>.<variable-name>'], 'true'))

Examples:

  1. At the first example, the 2 conditions MUST meet:
condition: and(succeeded(), contains(stageDependencies.Stg1.outputs['GettingVariable.vstat.vmname'], 'vm1'))

A. The previous stage was succeeded
&
B. The variables contain VM1

  • Notice that the condition’s syntax, between stages and jobs are DIFFERENT!
trigger: none

stages:
- stage: Stg1
jobs:
- job: GettingVariable
steps:
- task: AzureCLI@2
name: vstat
displayName: Get VM name variables
inputs:
connectedServiceNameARM: "DEMOSA"
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
$vmnameselected = (az vm list | ConvertFrom-Json).name
echo "##vso[task.setvariable variable=vmname;isOutput=true]$vmnameselected"
echo "variable vmname is $vmnameselected"

- stage: Stg2
dependsOn: stg1
condition: and(succeeded(), contains(stageDependencies.Stg1.outputs['GettingVariable.vstat.vmname'], 'vm1'))
jobs:
- job: TestVariable
steps:
- task: AzureCLI@2
displayName: dependency by variable
#condition: and(succeeded(), ne(variables['vmname'], 'vm1'))
inputs:
azureSubscription: 'DEMOSA'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
Write-Host "##[warning] listing resource groups"
(az group list | ConvertFrom-Json).name

The variables as we can see contain VM1 & VM2

Since BOTHS 2 contentions met, the second stage (dependency by vibrable) was executed.

2. At the second example, there are other 2 conditions that MUST meet:

    condition: and(succeeded(), not(contains(stageDependencies.Stg1.outputs['GettingVariable.vstat.vmname'], 'vm1')))

A. The previous task was succeeded
&
B. The variables should NOT contain VM1

Since only 1 contention was met, the second task (dependency by vibrable) was skipped.

Summery

Using different types of expressions and conditions, we can get a lot of possibilities manipulating our tasks, jobs and stages in our YAML files for different pipeline needs.

Knowing the variety of options allows us to implement the right pipeline according to our missions and projects.

--

--

Tzahi Kolber
Tzahi Kolber

Written by Tzahi Kolber

During the last 17 years, I was working as a Senior PFE within Exchange area at Microsoft. Now I’m Senior Consult as Azure IAAS, DevOps & Automations.

No responses yet