Passing variables between jobs for Azure DevOps pipelines
Using Azure DevOps, you can create pipeline variables dynamically. Out of the box, most dynamic variables are scoped to the job. But, if you need to, you can reference pipeline variables defined in other jobs. For example, if you have a stage that has multiple jobs because you need something done in Linux and something in Windows, then you can consume a dynamic pipeline variable created by another job.
Background
You might be familiar with how to set static pipeline variables through YAML.
variables:
someName: someValue
But, what if you want to create this variable using data from a task? For example, you want to dynamically provision Azure resources using a Terraform or ARM Template task. Then, you also want to set pipeline variables to represent the names of the resources so that you can deploy to that infrastructure.
You can set a dynamic pipeline variable by writing to the host console.
Powershell:
powershell: |
Write-Host "##vso[task.setvariable variable=someName;]someValue"
Bash:
bash: |
echo "##vso[task.setvariable variable=someName;]someValue"
Now, you will be able to use this like a regular pipeline variable.
powershell: |
Write-Host "The value of the pipeline variable is $(someName)"
But, you won’t be able to use this variable from a different job… yet. By default, it’s scoped to the job.
Variables from another job
Note: Shoutout to Maikel who caught a regression in the syntax and fixed the example below.
To make a variable accessible from another job, there’s a couple of things you want to do. Microsoft also has some documentation on this feature called output variables.
First, when creating the dynamic pipeline variable, specify that it’s an output variable.
powershell: |
Write-Host "##vso[task.setvariable variable=someName;isOutput=true;]someValue"
Then assuming you have multiple jobs, add a dependency from one job to another.
- job: job_deploy_code
displayName: Deploy Some Code
dependsOn: ['job_deploy_infrastructure']
Then define some a variable scoped to the job.
variables:
someName: $[ dependencies.job_deploy_infrastructure.outputs['setVariable.someName'] ]
Putting it all together
stages:
- stage: stage_deploy
displayName: Production
jobs:
- job: job_deploy_infrastructure
displayName: Deploy Some Infrastructure
steps:
- bash: |
SOMEVALUE="bleh"
echo "##vso[task.setvariable variable=someName;isOutput=true;]$SOMEVALUE"
echo "variable value is $(someName)"
- job: job_deploy_code
displayName: Deploy Some Code
dependsOn: ['job_deploy_infrastructure']
variables:
someName: $[ dependencies.job_deploy_infrastructure.outputs['setVariable.someName'] ]
steps:
- bash: |
"the variable value is $(someName)"