fandro
fandro

Reputation: 4903

Default parameters in nested yaml pipeline Azure DevOps

I have multiple resusable yaml templates to build my project using Azure DevOps. I want to let the default template values when I don't want to override it. The problem I have is when I nest multiple templates, it's not working as I expected, here is an example of my issue:

parameters:
  foo: 'data'

steps:
- task: Bash@3
  inputs: 
    targetType: 'inline'
    script: echo ${{ parameters.foo }}

Inside a job_template.yml I call this task_template1.yml like this:

parameters:
  fooTemplate: 'data'

jobs:
- job:
  steps:
    - template: task_template1.yml
      parameters:
        ${{ if variables[parameters.fooTemplate] }}:
          foo: ${{ parameters.fooTemplate }}

And then my global template:

stages:

- stage: Build
  jobs:
  - template: job_template.yml
    parameters:
      fooTemplate: 'hello'

So in this case, by default I expect that my variable fooTemplate will set the value of the variable foo inside my task_template1.yml to hello because I specify it. But it's not the case, because it looks like ${{ if variables[parameters.fooTemplate] }}: is evaluated before the build start so foo is set to data instead of hello. Conversely if I would like to keep the default value of fooTemplate (data) I just want to not specify it like this:

stages:

- stage: Build
  jobs:
  - template: job_template.yml

It looks like a problem of nested templates. How can I do to fit this two rules? Feel free to ask me some more details if needed.

EDIT:

I always have this message : 'foo has no value: undefined'

Other case that I have, instead of a simple parameter:

parameters:
  foo:'data'
  foo1:'data1'

steps:
- task: Bash@3
  inputs: 
    targetType: 'inline'
    script: echo ${{ parameters.foo }}

So for the job I have:

parameters:
  fooTemplate:
   foo:'data'
   foo1:'data1'

jobs:
- job:
  steps:
    - template: task_template1.yml
      parameters:
        ${{ if ne(parameters.fooTemplate.foo, ' ') }}:
          foo: ${{ parameters.fooTemplate.foo }}
        ${{ if ne(parameters.fooTemplate.foo1, ' ') }}:
          foo: ${{ parameters.fooTemplate.foo1 }}

And then same case if I don't specify the foo and foo1 value I have the undefined error, instead of taking the default values:

stages:

- stage: Build
  jobs:
  - template: job_template.yml

Upvotes: 2

Views: 4450

Answers (1)

LoLance
LoLance

Reputation: 28146

I think something is wrong with your syntax here:

parameters:
        ${{ if variables[parameters.fooTemplate] }}:
          foo: ${{ parameters.fooTemplate }}

Try this way(according to this):

parameters:
        ${{ if eq(parameters.fooTemplate, true) }}:
          foo: ${{ parameters.fooTemplate }}

It works on my side.

Notes:

You can have something like this:

parameters:
  fooTemplate: 'data'

jobs:
- job:
  steps:
    - template: task_template1.yml
      parameters:
        ${{ if ne(parameters.fooTemplate, ' ') }}:
          foo: ${{ parameters.fooTemplate }}

Now if you specify 'hello' in stage_build.yml, the task_template1.yml will output hello. And if you don't specify the parameter in stage_build.yml like this:

pool:
  vmImage: 'ubuntu-latest'

jobs:
- template: job_template.yml

It will output the default data. Here're more details about Expressions and Conditions.

Upvotes: 1

Related Questions