Azure Pipelines: Avoid repetition by using loops

I’ve seen a lot of YAML pipelines with the following structure:

pool: Azure Pipelines

stages:
- stage: Dev
  jobs:
  - job:
    displayName: "Deploy to: Dev"
    steps:
    - task: AzureCLI@2
      displayName: "Run Bicep against subscription: Dev"
      inputs:
        azureSubscription: Dev
        scriptType: pscore
        scriptLocation: inlineScript
        inlineScript: az deployment sub create -l uksouth -f main.bicep -p dev.bicepparam

- stage: Test
  jobs:
  - job:
    displayName: "Deploy to: Test"
    steps:
    - task: AzureCLI@2
      displayName: "Run Bicep against subscription: Test"
      inputs:
        azureSubscription: Test
        scriptType: pscore
        scriptLocation: inlineScript
        inlineScript: az deployment sub create -l uksouth -f main.bicep -p test.bicepparam

- stage: Production
  jobs:
  - job:
    displayName: "Deploy to: Production"
    steps:
    - task: AzureCLI@2
      displayName: "Run Bicep against subscription: Production"
      inputs:
        azureSubscription: Production
        scriptType: pscore
        scriptLocation: inlineScript
        inlineScript: az deployment sub create -l uksouth -f main.bicep -p production.bicepparam

    This can be improved to:

    pool: Azure Pipelines
    
    variables:
      environments: Dev,Test,Production
    
    stages:
    - ${{ each env in split(variables.environments, ',') }}:
      - stage: ${{ env }}
        jobs:
        - job:
          displayName: "Deploy to: ${{ env }}"
          steps:
          - task: AzureCLI@2
            displayName: "Run Bicep against subscription: ${{ env }}"
            inputs:
              azureSubscription: ${{ env }}
              scriptType: pscore
              scriptLocation: inlineScript
              inlineScript: az deployment sub create -l uksouth -f main.bicep -p ${{ lower(env) }}.bicepparam
    

    The benefits are:

    • Avoidance of copy/paste errors
    • Easier to modify e.g. if we want to use Azure PowerShell instead of the Azure CLI, we just need to make the change in one place
    • Easier to maintain because of above
    • Easier to follow what the YAML does
    • Can see what environments are targeted by just looking at the comma separated list, would otherwise have to scroll and scrutinise all the YAML
    • Even better, the list of environments can be placed in a variable template, this means we can update the environments that multiple pipelines deploy to by modifying a single file, making it easier to add and remove environments e.g.
      main.yml:
      variables:
      - template: environments.yml
    
      environments.yml:
      variables:
        environments: Dev,Test,Production
    

    Leave a comment