Azure pipeline: User-defined variable set in script not expanded when used in later step with template

759 Views Asked by At

I am trying to pass a variable, set by a ps1 script, as a parameter to a template yaml file in an azure pipeline yaml. However no matter what I try the variable is never expanded when it reaches the template.

parameters:
- name: myparam
  type: boolean
  default: 'true'

stages:
- stage: stage1
  variables:
    override: 'true'
  jobs:
    - job: FilterJob
    - task: PowerShell@2
      name: ps1task
      inputs:
        targetType: inline
        script: |
          $override = "some value"
          Write-Host "##vso[task.setvariable variable=override;isOutput=true]$override"

- ${{ if eq(parameters.myparam, true) }}:
  - template: Mytemplate.yml
    parameters:
      varPassedToTemplate: $(variables.override) ### VARIABLE DOES NOT EXPAND

The variable 'varPassedToTemplate' always ends up as a litteral of whatever is after the ':' I believe ${{ if eq(parameters.myparam, true) }}: is compile time and isn't expanded during runtime but does that also apply to params passed to a template? Is there a way to expand the variable 'varPassedToTemplate' or is my syntax just wrong? (BTW I have tried multiple syntaxes)

This has been driving me crazy for days so any help much appreciated.

2

There are 2 best solutions below

0
On

Based on your YAML sample, you are defining the Stages or Jobs in the Template.

The variables you define in stage1 cannot be passed directly to the next stage or job.

To solve this issue, I suggest that you can define the jobs in the template and use Stage output variable to accept the variable in stage1.

Refer to my sample:

Template:

parameters:
- name: varPassedToTemplate 
  type: string 
  default: test

jobs:
  - job: FilterJob
    steps:
        - task: PowerShell@2
          inputs:
            targetType: 'inline'
            script: |
              echo ${{ parameters.varPassedToTemplate }}

main YAML:

parameters:
- name: myparam
  type: boolean
  default: 'true'

stages:
- stage: stage1
  variables:
    override: 'true'
  jobs:
    - job: FilterJob
      steps:
        - task: PowerShell@2
          inputs:
            targetType: 'inline'
            script: |
              $override = "some value"
              Write-Host "##vso[task.setvariable variable=override;isOutput=true]$override"
          name: test

- ${{ if eq(parameters.myparam, true) }}:
   - stage: stage2
     variables:
       override: $[ stageDependencies.stage1.FilterJob.outputs['test.override'] ] 
     jobs:
       - template: template.yml
         parameters:
          varPassedToTemplate: $(override)

Result:

enter image description here

0
On

Another option is to use output variables within the same job. The name you used for your powershell task is ps1task, ad the name of the variable you defined within this task is override. You could expand your user-defined variable - override - within the same job as ps1task the following way:

$(ps1task.override)

So, changing the stage2 for the below should make it work!

- ${{ if eq(parameters.myparam, true) }}:
  - template: Mytemplate.yml
    parameters:
      varPassedToTemplate: $(ps1task.override)