2

I know that in Azure DevOps, variables accessed like $(varname) are runtime only. But I'm struggling to understand why my code below doesn't work when I am accessing it using the compile time syntax

This is a shortened down version on my pipeline. Basically, I have the main pipeline file, then each environment (dev, etc) will have it's own .yml. This is just for organizational purposes. Each environment file will call a set of stages

azure-pipeline.yml

variables:
  - name: myVar
    value: 'one'

stages:
  # Deploy Dev
  - template: ./azure-pipeline-dev.yml
    

azure-pipeline-dev.yml

stages:
  - template: ./deploy.yml
    parameters: 
      myParam: ${{ variables.myVar }}

deploy.yml

parameters:
  - name: myParam
    type: string
    values:
      - one
      - two

When I do this I get an error saying:

/azure-pipeline-dev.yml The 'myParam' parameter value '' is not a valid value.

But my question is, since I am using the compile time syntax, why is the value not being loaded into the ${{ variables.myVar }}

2 Answers 2

3

This is an old question, but in case it's helpful to anyone, you can absolutely use the global variable in the templates, you just have to reference it as a variable instead of a parameter. That is, you could freely refer to $(myVar) in either azure-pipeline-dev.yml or deploy.yml

This works fine:

azure-pipeline.yml

trigger:
- none

variables:
  - name: myVar
    value: one

stages:
  # Deploy Dev
  - template: ./azure-pipeline-dev.yml

azure-pipeline-dev.yml

stages:
  - template: ./deploy.yml
    parameters:
      myParam: $(myVar) 

deploy.yml

parameters:
  - name: myParam
    type: string
  
stages:
- stage: A
  jobs:
  - job: A1
    steps:
    - script: echo ${{parameters.myParam}}
      displayName: 'Run a one-line script'

or just this:

azure-pipeline.yml

trigger:
- none

variables:
  - name: myVar
    value: one

stages:
  # Deploy Dev
  - template: ./azure-pipeline-dev.yml

azure-pipeline-dev.yml

stages:
  - template: ./deploy.yml

deploy.yml

stages:
- stage: A
  jobs:
  - job: A1
    steps:
    - script: echo $(myVar)
      displayName: 'Run a one-line script'
Sign up to request clarification or add additional context in comments.

Comments

1

I am able to reproduce your issue:

enter image description here

The issue comes from you didn't have the step to pass variables.

But my question is, since I am using the compile time syntax, why is the value not being loaded into the ${{ variables.myVar }}

template need parameter section to pass values, and only this way can pass values to template.

By the way, your definition has other problems. First, you didn't have stages structure in deploy.yml. Second, variables always string, compile time can't give the deploy.yml array via variables. Only parameters can achieve this.

azure-pipelines.yml

trigger:
- none

variables:
  - name: myVar
    value: one


stages:
  # Deploy Dev
  - template: ./azure-pipeline-dev.yml
    parameters: 
      myVar: ${{ variables.myVar }}

azure-pipeline-dev.yml

parameters:
  - name: myVar
    type: string
    default: 'xxx'

stages:
  - template: ./deploy.yml
    parameters: 
      myParam: ${{ parameters.myVar }} 

deploy.yml

parameters:
  - name: myParam
    type: string
    default: xxx
    # values:
    #   - one
    #   - two
stages:
- stage: A
  jobs:
  - job: A1
    steps:
    - script: echo ${{parameters.myParam}}
      displayName: 'Run a one-line script'

This will fine on my side:

enter image description here

1 Comment

Thanks a lot for the clarification. I was thinking I needed to pass the var in as a parameter but was hoping I could just use the global variable syntax as it would look a lot tidier. Apologies about the formatting, I was copying and redacting my var names, etc

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.