Given the following Azure DevOps pipeline template:
parameters:
- name: AUTH_TYPE
type: string
steps:
- task: Bash@3
displayName: Parameter print
inputs:
targetType: inline
script: echo "AUTH_TYPE = '${{ parameters.AUTH_TYPE }}'"
- task: Bash@3
displayName: Variable print
inputs:
targetType: inline
script: echo "AUTH_TYPE = '${{ variables.AUTH_TYPE }}'"
- task: Bash@3
displayName: OIDC auth
inputs:
targetType: inline
script: echo OIDC authentication
condition: ${{ eq(parameters.AUTH_TYPE, 'oidc') }}
- task: Bash@3
displayName: Password auth
inputs:
targetType: inline
script: echo Password authentication
condition: ${{ eq(parameters.AUTH_TYPE, 'password') }}
Calling:
# ...
variables:
- group: pipeline-vars
steps:
- checkout: shared-library
- template: pipeline-templates/auth.yaml@shared-library
parameters:
AUTH_TYPE: $(AUTH_TYPE)
The problem is, the Parameter print
outputs the AUTH_TYPE value correctly (oidc in the example) but the corresponding OIDC auth
task condition evaluates to false (it is skipped in the pipeline run).
Can anyone help me what is wrong with this? I am totally new in Azure DevOps Pipelines and I currently struggling with understanding how the templates evaluated by the runtime.
In your Calling YAML, you are passing $(AUTH_TYPE)
as a parameter to the template. The $(AUTH_TYPE)
appears to be a variable defined within the pipeline-vars
variable group.
In the Context of Template expressions:
Within a template expression, you have access to the parameters context that contains the values of parameters passed in. Additionally, you have access to the variables context that contains all the variables specified in the YAML file plus many of the predefined variables (noted on each variable in that article). Importantly, it doesn’t have runtime variables such as those stored on the pipeline or given when you start a run. Template expansion happens early in the run, so those variables aren’t available.
In your case, the parameter in condition: ${{ eq(parameters.AUTH_TYPE, 'oidc') }}
is evaluated at compile time. At compile time, the variable $(AUTH_TYPE)
is not available and you are passing the empty $(AUTH_TYPE)
as a parameter to the template, so the parameters.AUTH_TYPE
is also empty. This is why the condition in your task evaluates to false.
To make the pipeline template work as you want, you can define AUTH_TYPE
as parameters instead of the variable.
parameters:
- name: AUTH_TYPE
type: string
default: 'oidc' # or 'password', depending on what you want
steps:
- checkout: shared-library
- template: pipeline-templates/auth.yaml@shared-library
parameters:
AUTH_TYPE: ${{ parameters.AUTH_TYPE }}
Your template yaml looks good with slight modification, I have just test it and the OIDC auth
condition works.
But you can not pass the variable into template parameters. the template yaml be compiled to a big-yaml
will accept the parameters at compile time, but variables values work in run-time.
parameters:
- name: AUTH_TYPE
type: string
default: 'oidc'
variables:
- name: var1
value: ${{ parameters.AUTH_TYPE }}
steps:
- task: Bash@3
displayName: Parameter print
inputs:
targetType: inline
script: echo "AUTH_TYPE = ${{ parameters.AUTH_TYPE }}"
- task: Bash@3
displayName: Variable print
inputs:
targetType: inline
script: echo "AUTH_TYPE = ${{ variables.var1 }}"
- task: Bash@3
displayName: OIDC auth
inputs:
targetType: inline
script: echo OIDC authentication
condition: ${{ eq(parameters.AUTH_TYPE, 'oidc') }}
- task: Bash@3
displayName: Password auth
inputs:
targetType: inline
script: echo Password authentication
condition: ${{ eq(parameters.AUTH_TYPE, 'password') }}