'Can an Azure YAML Pipelines <deployment job> use variable environments?

I read the environments documentation here and the issues opened under the environment resource, however I find it impossible to achieve my goal:

I would like to use a parametrized yaml template in order to deploy to multiple environments like below:

parameters:
  pool_name: ''
  aks_namespace: ''
  environment: ''

jobs:
  - job: preDeploy
    displayName: preDeploy
    pool:
      name: $(pool_name)
    steps:
      - template: cd_step_prerequisites.yml


  - deployment: Deploy
    displayName: Deploy
    dependsOn: preDeploy
    condition: succeeded()
    variables:
      secret_name: acrecret
    pool:
      name: dockerAgents
    **environment: '$(environment).$(aks_namespace)'**
    strategy:
      runOnce:
        deploy:
          steps:
          - template: cd_step_aks_deploy.yml


  - job: postDeploy
    displayName: postDeploy
    dependsOn: Deploy
    condition: succeeded()
    pool:
      name: $(pool_name)
    steps:
      - template: cd_step_postrequisites.yml

I would like to use this approach so that I only host a minimal pipeline.yml next to my code, and then I would have all the templates in a different repo and call them from the main pipeline, as such:

resources:
  repositories:
    - repository: self
    - repository: devops
      type: git
      name: devops

  - stage: CD1
    displayName: Deploy to Alpha
    jobs:
      **- template: pipeline/cd_job_api.yml@devops**
        parameters:
          pool_name: $(pool_name)
          aks_namespace: $(aks_namespace)
          app_name: $(app_name)
          app_image_full_name: $(app_image_full_name)
          environment: alpha

Then I would be able to pass the $environment variable in order to manipulate multiple deployment targets (AKS clusters/ groups of namespaces) from one template. Currently this seems to be impossible as the default AzureDevOps parser fails when I try to run my pipeline, with the message "$(environment) environment does not contain x namespace" which tells me that the variable doesn't get expanded.

Is this planning to be implemented anytime soon? If not, are there any alternatives to use only one parametrized job template to deploy to multiple environments?



Solution 1:[1]

I think you would need to either parse the files and do a token replace with a script or there should be steps for that.

Your main alternative would be helm. It allows to create templates and pass in variables to render those templates.

Solution 2:[2]

Maybe I'm a bit late to the party, but I was also struggling with this problem and found this open thread.

I found this "closed" issue on github. The key points for me in the issue are this comment with a partial solution and this other comment pointing to the explanation of why is not working. Quoting Microsoft's article:

It also answers another common issue: why can't I use variables to resolve service connection / environment names? Resources are authorized before a stage can start running, so stage- and job-level variables aren't available. Pipeline-level variables can be used, but only those explicitly included in the pipeline. Variable groups are themselves a resource subject to authorization, so their data is likewise not available when checking resource authorization.

Regarding the solution, based on the first comment I reference, I ended up creating a new Variable Group with variables with the following naming convention: product.environment.varname. Then I added this group to the beginning of the pipeline (global scope) and then referenced the variables using macro syntax: $(var)

Quick example:

variables:
  - group: Product.Pipelines.Environments

jobs:
  - job: preDeploy
    displayName: preDeploy
    pool:
      name: $(pool_name)
    steps:
      - template: cd_step_prerequisites.yml

  - deployment: Deploy
    displayName: Deploy
    dependsOn: preDeploy
    condition: succeeded()
    variables:
      secret_name: acrecret
    pool:
      name: dockerAgents
    environment: $(product.dev.environmentname) #this is the variable within the variable group
    strategy:
      runOnce:
        deploy:
          steps:
          - template: cd_step_aks_deploy.yml

The variable group will contain among other variables:

  • product.dev.environmentname: Development
  • product.stg.environmentname: Staging
  • product.prd.environmentname: Production

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 4c74356b41
Solution 2 Dharman