Conditionally Set Environment Azure DevOps

Viewed 398

I am working with an Azure Pipeline in which I need to conditionally set the environment property. I am invoking the pipeline from a rest API call by passing Parameters in the body which is documented here.. When I try to access that parameter at compile time to set the environment conditionally though the variable is coming through as empty (assuming it is not accessible at compile time?)

enter image description here

enter image description here

Does anybody know a good way to solve for this via the pipeline or the API call?

2 Answers

After some digging I have found the answer to my question and I hope this helps someone else in the future.

As it turns out the Build REST API does support template parameters that can be used at compile time, the documentation just doesn't explicitly tell you. This is also supported in the Runs endpoint as well.

My payload for my request ended up looking like:

{
    "Parameters": "{\"Env\":\"QA\"}",
    "templateParameters": {"SkipApproval" : "Y"},
    "Definition": {
        "Id": 123
    },
    "SourceBranch": "main"
}

and my pipeline consumed those changes at compile time via the following (abbreviated version) of my pipeline

parameters:
  - name: SkipApproval
    default: ''
    type: string
...
        ${{if eq(parameters.SkipApproval, 'Y')}}: 
            environment: NoApproval-All
        ${{if ne(parameters.SkipApproval, 'Y')}}:
            environment: digitalCloud-qa

This is a common area of confusion for YAML pipelines. Run-time variables need to be accessed using a different syntax.

$[ variable ]

YAML pipelines go through several phases.

  1. Compilation - This is where all of the YAML documents (templates, etc) comprising the final pipelines are compiled into a single document. Final values for parameters and variables using ${{}} syntax are inserted into the document.
  2. Runtime - Run-time variables using the $[] syntax are plugged in.
  3. Execution - The final pipeline is run by the agents.

This is a simplification, another explanation from Microsoft is a bit better:

  1. First, expand templates and evaluate template expressions.
  2. Next, evaluate dependencies at the stage level to pick the first stage(s) to run.
  3. For each stage selected to run, two things happen:
    • All resources used in all jobs are gathered up and validated for authorization to run.
    • Evaluate dependencies at the job level to pick the first job(s) to run.
  4. For each job selected to run, expand multi-configs (strategy: matrix or strategy: parallel in YAML) into multiple runtime jobs.
  5. For each runtime job, evaluate conditions to decide whether that job is eligible to run.
  6. Request an agent for each eligible runtime job.

...

This ordering helps answer a common question: why can't I use certain variables in my template parameters? Step 1, template expansion, operates solely on the text of the YAML document. Runtime variables don't exist during that step. After step 1, template parameters have been resolved and no longer exist.

[ref: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/runs?view=azure-devops]

Related