Passing variables in Azure Pipelines YAML tasks, jobs and stages.
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:
- Variables: Define variables — Azure Pipelines | Microsoft Learn
- Dependencies and conditions: Stages in Azure Pipelines — Azure Pipelines | Microsoft Learn
- Expressions: Expressions — Azure Pipelines | Microsoft Learn
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:
- 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.
- 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:
- 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.
- By the way, you use many types of conditions like:
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:
- 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.
- 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:
- 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:
- 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.
- 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:
- 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.