2

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:

  • task_template1.yml:
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:

  • job_template.yml:
parameters:
  fooTemplate: 'data'

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

And then my global template:

  • stage_build.yml:
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

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

13 Comments

Thanks for your answer, yes it works for boolean, but what about strings, or numbers, If you don't set it, it will be "undefined" and I don't find how undefined can be tested during the build.
I'm not sure about what "undefined" means. eq(parameters.fooTemplate, 'string')?Could you share some details about how I can reproduce the same issue to check that?
To reproduce it, replace the enable value to a string value and you will see that the default parameter is not set inside the task_template1.yml, it will show you an example of undefined when you not specify it instead of the default value
Yes sure, I updated the question with examples and explantations. I think it's not a similar issue.
Thanks, I will give some try and go back to you :)
|

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.