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