Azure DevOps Pipeline for Bicep and ARM deployments
Sometimes simple is better. When infrastructure team first start taking on cloud infrastructure they need to get up to speed quickly with infrastructure as code and pipeline deployments. And sometimes we as devops engineers can complicate matters by introducing pipelines that are too complex in nature. This is a simple pipeline that can be used to deploy Bicep and ARM templates to Azure.
Prerequisites
- Azure DevOps Project
- Service Connection to your Azure Subscription (make sure this is scoped in at the subscription level)
- Azure DevOps Environment
Environments
Before you run the pipeline for the first time ensure you configure an environment in your azure devops project and add some approvers to the environment. Check this article to learn how to create an environment in Azure DevOps: Environments Define Approvals and Checks
Pipeline
The code below is a YAML file that represents an Azure DevOps pipeline for Infrastructure as Code (IaC) deployment using ARM templates or Bicep templates. Here's a breakdown of the key components:
- The pipeline is named "IaC deployment to RG" followed by the value of the
ResourceGroupName
parameter. - The pipeline is triggered when changes are made to the
main
branch. - The pipeline runs on an Ubuntu agent (
vmImage: ubuntu-latest
). - The pipeline accepts several parameters, including
AzureServiceConnection
,DeploymentName
,PreviewChanges
,ResourceGroupName
,TemplateFilePath
, andTemplateParameterFilePath
. - The
AzureServiceConnection
parameter allows you to specify the Azure service connection to use for the deployment. you can add multiple service connections to your Azure subscriptions in the values section. this will show up as radio buttons in the pipeline ui when you run the pipeline. - The
DeploymentName
parameter is used to provide a name for the ARM deployment. - The
PreviewChanges
parameter is a boolean value that enables or disables the what-if preview for the deployment. I would suggest keeping this enabled to allow you to verify the changes before they are deployed. - The
ResourceGroupName
parameter specifies the target resource group for the deployment. - The
TemplateFilePath
parameter is the path to the template file (ARM or Bicep) used for the deployment. - The
TemplateParameterFilePath
parameter is the path to the parameter file (ARM or Bicep) used for the deployment.
The pipeline consists of two stages:
-
Preview_Deployment
stage: This stage is conditionally executed when thePreviewChanges
parameter is set totrue
. It contains a single job namedPreview
that uses the Azure CLI task to perform a what-if deployment to the specified resource group. TheinlineScript
property of the task executes theaz deployment group what-if
command with the provided parameters. -
Live_Deployment
stage: This stage is executed when the previous stage succeeds. It contains a single deployment job namedDeployment
. The job is associated with an environment called "IaC Deployment Approval" (which needs to be created in Azure DevOps). The job uses the Azure CLI task to perform the actual deployment to the specified resource group. TheinlineScript
property of the task executes theaz deployment group create
command with the provided parameters.
name: IaC deployment to RG ${{ parameters.ResourceGroupName }}
trigger:
- main
pool:
vmImage: ubuntu-latest
parameters:
- name: 'AzureServiceConnection'
type: string
values: # here you can add all your service connections to your Azure subscriptions.
- "Dries - VS Enterprise Subscription"
- name: DeploymentName # Name for ARM Deployment
type: string
default: "<Insert name for deployment>"
- name: ResourceGroupName # Resource Group to deploy to
type: string
default: '<Insert the target resource group name>'
- name: TemplateFilePath # Path to the template file (can be an ARM or Bicep template file)
type: string
default: '<Insert path to template file>'
- name: TemplateParameterFilePath # Path to the parameter file (can be an ARM or Bicep template file)
type: string
default: '<Insert path to parameter file>'
stages:
- stage: Preview_Deployment
jobs:
- job: Preview
steps:
- powershell: |
Write-Output "Listing the Azure DevOps pipeline agent directory with downloaded artifacts"
Write-Output "--START----------------"
ls -R $(System.DefaultWorkingDirectory)/
Write-Output "--END------------------"
displayName: 'List Artifacts'
condition: succeeded()
continueOnError: false
- task: AzureCLI@2
displayName: What-If Deploy to Resource Group
inputs:
azureSubscription: ${{ parameters.AzureServiceConnection }}
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group what-if `
--name '${{ parameters.DeploymentName }}' `
--resource-group '${{ parameters.ResourceGroupName }}' `
--template-file '$(System.DefaultWorkingDirectory)/${{ parameters.TemplateFilePath }}' `
--parameters '$(System.DefaultWorkingDirectory)/${{ parameters.TemplateParameterFilePath }}'
- stage: Live_Deployment
jobs:
- deployment: Deployment
displayName: Deploy Deployment
environment: 'IaC Deployment Approval' #this is the environment that you will need to create in ADO
strategy:
runOnce:
deploy:
steps:
- checkout: self
- task: AzureCLI@2
displayName: Deploy to Resource Group
inputs:
azureSubscription: ${{ parameters.AzureServiceConnection }}
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group create `
--name '${{ parameters.DeploymentName }}' `
--resource-group '${{ parameters.ResourceGroupName }}' `
--template-file '$(System.DefaultWorkingDirectory)/${{ parameters.TemplateFilePath }}' `
--parameters '$(System.DefaultWorkingDirectory)/${{ parameters.TemplateParameterFilePath }}'