skip to Main Content

Edit 1: In the original post I have a typo: inside step #4 I used compile-time expressions which is not correct of course, and in my original pipeline I am using template expressions. Sorry for the confusion – now YAML snippets in this post are identical to my pipeline. And yes, it’s still not working.
Screenshot of execution

Because of some reason, I have some trouble while using template expressions syntax (If-else statement especially) with variables that are imported from a template. Which broking all logic of my pipeline.
So, I have a quite simple ADO Yaml pipeline:
azure-pipelines.yml

parameters:
  - name: applicationType
    type: string
    values:
    - Backend
    - Frontend
    - Others
    default: Backend

trigger: none
resources:
    repositories:
    - repository: Templates
      type: git
      name: Templates

variables:
 - name: applicationType
  value: ${{ parameters.applicationType }}
 - template: vars/vars.yml@Templates
   parameters:
     varAppType:$(applicationType)

stages:
  - stage: Test
    jobs:
      - job: Test
        pool:
          vmImage: ubuntu-latest
        steps:
        - bash: echo $(applicationType) #1
        - ${{ if eq(variables.applicationType, 'Backend') }}: #2
          - bash: echo "It is Backend" 
        - ${{ else }}:
          - bash: echo "It is something different"
        - bash: echo $(varAppType) #3
        - ${{ if eq(variables.varAppType, 'Backend') }}: #4
          - bash: echo "It is Backend" 
        - ${{ else }}:
          - bash: echo "It is something different" 

And here is the snippet of vars/vars.yml which located in Templates repo:

parameters:
    - name: varAppType
      default: ''

variables:
- name: varAppType
  value: ${{ parameters.varAppType }}

Everything looks fine and straightforward, but here is what I see in logs during the run if I set applicationType as ‘Backend’:

#1 output: Backend
#2 output: It is Backend
#3 output: Backend
#4 output: It is something different

Because conditionals only work when used with template syntax I don’t even know what else I can try to do.
Its strange why ADO making such a difference between typical vars and imported from template ones, as I thought it should be working well because template syntax get processed at compile time, before runtime starts.
Maybe somebody knows how to fix this and what point I am missing with such a trivial task.
Any help would be appreciated, so thanks in advance.

2

Answers


  1. For #4 you are using runtime expression ($[]), while for #2 – compile-time expression (${{}}). Conditional insertion can work only with compile-time expressions, that’s why #4 is not working. More info about expressions: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops

    To solve your problem you can try to change your pipeline in a way that you would use compile-time expressions or use condition field which is present in any step. In second option it would be possible to use runtime expressions

    Login or Signup to reply.
  2. You’re mixing different types of variables.

     - template: vars/vars.yml@Templates
       parameters:
         varAppType:$(applicationType)
    

    $(applicationType) is macro syntax, which is evaluated at runtime. However, template parameters are resolved at compilation time. Thus, varAppType:$(applicationType) should actually be varAppType: ${{ variables.applicationType }} (or more ideally, ${{ parameters.applicationType }}) so it can be resolved at compilation time.

    However, the mapping of parameters into variables that you’re doing is largely unnecessary. You can just reference the parameter directly as ${{ parameters.applicationType }} throughout. As such, your entire vars.yml template is unnecessary.

    Another best practices note:

    What you’re doing here:

    - bash: echo $(applicationType) is potentially dangerous. Just like SQL injection, you’re taking an arbitrary string and injecting it directly into a script. This is called a script injection vulnerability.

    The better way to handle this is to map your parameter into an environment variable and reference it as an environment variable within your script, as follows:

    - bash: echo $APP_TYPE
      env:
       APP_TYPE: ${{ parameters.applicationType }}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search