Azure pipelines - Passing variables across stages
Tags: azuredevops, azurepipelinesvariables, azurepipelinesstages
Published: 2024-02-17 10:50:43

The following code block explains passing the variable 'agentvalue' to the StopVM stage. 

**Code explanation**:

In the StartVM stage, the variable 'agentvalue' is declared and the agentname value is assigned to the variable 'agentvalue'. Task name 'setagentname' has to be defined for the task if a variable is defined.

In the StopVM stage, the variable called 'VirtualMachine' is created to access the output of agentvalue. The 'VirtualMachine' is accessed only within that stage. 
Any variable can only be accessed within that stage after defined.

The dependsOn condition on the StopVM stage is dependent with StartVM and Cleanup stages to complete their executions to continue with StopVM stage.

By default in azure pipelines, the second stage is dependent to the first stage - third to second and so on. If we have only the second stage (Build stage) and StopVM stage, then these two stages will be executed parallely once StartVM stage is completed.

**Syntax**:

To use the output from a different stage, the format for referencing variables is stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE']

To reference a variable from a task from a different job, use dependencies.JOB.outputs['TASK.VARIABLE']



```
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
  - none 
  
name: $(TeamProject)-$(SourceBranchName)-$(Build.BuildId)-$(Hours)$(Minutes)$(Seconds)-$(Date:yyyyMMdd)$(Rev:.r)
  
pool:
  name: test

parameters:
- name: WarGeneration
  displayName: Run WarGeneration
  type: boolean
  default: false
      
stages:
- stage: StartVM
  displayName: StartVM
  jobs:
  - job: StartVM
    timeoutInMinutes: 0
    displayName: StartVM
    pool:
      name: Azure Pipelines
    steps:
    - checkout: none
    - task: AzureKeyVault@2
      inputs:
        azureSubscription: 'xxx'
        KeyVaultName: 'xxx'
        SecretsFilter: 'xxx,yyy'
        RunAsPreJob: true
    - task: CmdLine@2
      inputs:
        script: |
          az login --service-principal --username $(xxx) --password $(xxx)  --tenant $(xxx)
                              	                      flag=true;
                                                          echo $flag
                                                          while ($flag); do
                                                          vmstatusvm1=`az vm show -g xxx -n vm1 -d --query powerState -o tsv`
                                                          vmnamevm1=`az vm show -g xxx -n vm1 -d --query name -o tsv`
                                                          vmstatusvm2=`az vm show -g xxx -n vm2 -d --query powerState -o tsv`
                                                          vmnamevm2=`az vm show -g xxx -n vm2 -d --query name -o tsv`
                                                          
                                                          if [[ $vmstatusvm1 == 'VM deallocate' && $vm1 == 'vm1' ]]; then
                                                            agentname=vm1
                                                            echo $agentname
                                                            az vm start --resource-group xxx --name $agentname
                                                            echo "##vso[task.setvariable variable=agentvalue;isOutput=true]$agentname"
                                                            flag=false
                                                           elif [[ $vmstatusvm2 == 'VM deallocated' && $vm2 == 'vm2' ]]; then
                                                            agentname=vm2
                                                            echo $agentname
                                                            az vm start --resource-group xxx --name $agentname
                                                            echo "##vso[task.setvariable variable=agentvalue;isOutput=true]$agentname"
                                                            flag=false
                                                          else
                                                            echo "There are no VM's available to trigger a new build."
                                                          fi  
                                                          done
                                                          
                    				                              
      name: setagentname    
                                                
          
          
- stage: Build
  displayName: Build stage
  jobs:
  - job: Build
    timeoutInMinutes: 0
    displayName: Build
    steps:
    - checkout: none
    - task: Bash@3
      inputs:
        targetType: 'inline'
        script: |
          echo "Printing virtual none"
          
- ${{ if eq(parameters.WarGeneration, true) }}:
  - stage: WarGeneration
    displayName: WarGeneration
    jobs:
    - job: War
      timeoutInMinutes: 0 
      displayName: War
      pool:
        name: test
        demands:
        - Agent.OS -equals Linux
      steps:
      - checkout: none            
      - task: AzureKeyVault@2
        inputs:
          azureSubscription: 'xxx'
          KeyVaultName: 'xxx'
          SecretsFilter: 'xxx'
          RunAsPreJob: true

- stage: Cleanup
  displayName: Cleanup stage
  condition: always()
  jobs:
  - job: CleanupJob
    timeoutInMinutes: 0 
    displayName: Cleanup Job
    pool:
     name: test
     demands:
     - Agent.OS -equals Linux
    steps:
      - checkout: none    
      - task: PowerShell@2
        displayName: Cleanup Task
        inputs:
          targetType: 'inline'
          script: |
            echo "Cleanup"
            
- stage: StopVM
  displayName: StopVM stage
  dependsOn:
  - StartVM
  - Cleanup
  condition:  always()
  variables:
    - name: VirtualMachine
      value: $[ stageDependencies.StartVM.StartVM.outputs['setagentname.agentvalue'] ]
  jobs:
  - job: StopVM
    timeoutInMinutes: 0
    displayName: StopVM
    pool:
      name: Azure Pipelines
    steps:
    - checkout: none
    - task: AzureKeyVault@2
      inputs:
        azureSubscription: 'xxx'
        KeyVaultName: 'xxx'
        SecretsFilter: 'xxx,yyy'
        RunAsPreJob: true
    
    - task: Bash@3
      inputs:
        targetType: 'inline'
        script: |
         az login --service-principal --username $(xxx) --password $(xxx)  --tenant $(xxx)
         az vm deallocate --resource-group xxx --name $(VirtualMachine)
```
Reference link:

[Use outputs in a different stage - section from link]
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#set-in-script