If you haven't already, please check out the previous parts of this series.
Part 2 - Deploying Bicep with AZ CLI
Extra Credit - My Advanced Bicep Guide
Deploying Bicep with Azure DevOps Pipelines
Azure DevOps Pipelines has a built-in task called ARMTemplateDeployment. As of version 3.199.0 this task can be used to deploy Bicep files. This task is a little strange, and it has a few quirks and important drawbacks versus the other deployment methods. I will go through all the quirks and drawbacks in this article.
This article assumes you already know how to work with YAML-based Azure DevOps Pipelines. This will not be a guide to using YAML, nor will it be a guide to building a full Azure DevOps Pipeline. This will be focused specifically on the ARMTemplateDeployment task and its various options.
One important point to make is that this task does not support every Azure deployment scope. It supports Resource Group, Subscription, and Management Group deployments. But, as of the time of this writing, it does NOT support Tenant deployments. Below, I will go over the nuances of using the task for the 3 deployment scopes that are supported.
A big drawback of this task is that it does not support the -WhatIf switch, so you will not be able to verify the changes that your deployment wants to make. You will have to go through the deployment blindly and hope for the best.
Another drawback of this task is that it does not support multi-line strings in your template or parameter file.
Deploying to a Resource Group
This section goes over how to use the task to deploy a Bicep file that has a targetScope set to resourceGroup. Remember, if your Bicep file does not have a targetScope line at the top, then by default, the value of resourceGroup is automatically used. Here are all of the options that apply when doing a Resource Group deployment.
deploymentScope
This must be set to Resource Group
This is optional. If omitted, the default value of Resource Group will be used
azureResourceManagerConnection
Enter the name of the Azure DevOps Service Connection that will be used for this deployment
An alias that can be used in place of this is ConnectedServiceName
subscriptionId
Enter in the Subscription which contains the Resource Group that you are deploying to.
An alias that can be used in place of this is subscriptionName
This is optional if you also specify an azureResourceManagerConnection that is scoped to a Subscription. In that case, if subscriptionId is omitted, the default value that will be used is the Subscription that is configured on your Azure DevOps Service Connection
If your chosen azureResourceManagerConnection is scoped to a Management Group, then subscriptionId is required.
action
For Resource Group deployments you can pick an action to perform:
Create Or Update Resource Group
This is usually the option you want and simply means that you are deploying to a Resource Group
One nice thing about this task is that it will create the Resource Group if it does not already exist
DeleteRG
I won't be going into detail on that option in this article
This is optional. If omitted, the default option of Create Or Update Resource Group is used.
resourceGroupName
Enter the name of the Resource Group that you are deploying to. Again, if this does not exist then it will be created.
location
This is only used if the Resource Group does not exist and must be created. If so, it will be created in the region that you specify here.
If the Resource Group already exists, then this line is ignored. However, it is still required to fill in a value here even if the Resource Group already exists.
deploymentMode
Incremental simply deploys the resources that are defined in your Bicep file. It doesn't care what other resources may reside in the Resource Group
Complete mode uses the Bicep file as the ultimate source of truth. Be careful with this option. If you have existing resources in the Resource Group, and those existing resources are not defined in your Bicep file, then those existing resources will be deleted. Likewise, if you remove a resource's code from your Bicep file, then that resource will be deleted from the Resource Group
Validation checks the Bicep file for syntax errors and won't deploy anything. One important thing to note: this mode will create the Resource Group if it does not already exist. It will end up being a blank Resource Group, but it will still be created
This is optional. If omitted, the default value of Incremental is used
Deploying to a Subscription
This section goes over how to use the task to deploy a Bicep file that has a targetScope set to subscription. Here are all of the options that apply when doing a Subscription deployment.
deploymentScope
Must be set to Subscription
azureResourceManagerConnection
Enter the name of the Azure DevOps Service Connection that will be used for this deployment
An alias that can be used in place of this is ConnectedServiceName
subscriptionId
Enter the Subscription that you are deploying to
An alias that can be used in place of this is subscriptionName
This is optional if you also specify an azureResourceManagerConnection that is scoped to a Subscription. In that case, if subscriptionId is omitted, the default value that will be used is the Subscription that is configured on your Azure DevOps Service Connection
If your chosen azureResourceManagerConnection is scoped to a Management Group, then subscriptionId is required.
location
This specifies the region used to store data about your deployment
deploymentMode
Incremental simply deploys the resources that are defined in your Bicep file. It doesn't care what other resources may reside in the Subscription
Validation checks the Bicep file for syntax errors and won't deploy anything
This is optional. If omitted, the default value of Incremental is used
Deploying to a Management Group
This section goes over how to use the task to deploy a Bicep file that has a targetScope set to managementGroup. Here are all of the options that apply when doing a Management Group deployment.
deploymentScope
Must be set to Management Group
azureResourceManagerConnection
Enter the name of the Azure DevOps Service Connection that will be used for this deployment
An alias that can be used in place of this is ConnectedServiceName
The Azure DevOps Service Connection that you pick must be scoped to a Management Group
location
This specifies the region used to store data about your deployment
deploymentMode
Incremental simply deploys the resources that are defined in your Bicep file. It doesn't care what other resources may reside in the Management Group
Validation checks the Bicep file for syntax errors and won't deploy anything
This is optional. If omitted, the default value of Incremental is used
Wait, how do I specify which Management Group to deploy to? Well, the Management Group that is tied to your chosen azureResourceManagerConnection will be used automatically.
Deploying to a Tenant
This task does NOT support deploying a Bicep file that has a targetScope set to tenant
Options that are common to all 3 Deployment Scopes
deploymentName
This specifies the name for this deployment. You may need to reference this deployment in the future, so it can be beneficial to use good names here
If you use the same deployment name over and over, then you will be restricted to viewing information about the latest deployment only. In other words, new deployments will overwrite the deployment data of old deployments if you use the same deployment name
This is optional. If omitted, a default unique value is used. The value is a combination of your Bicep filename, the date and time, and some other random characters.
templateLocation
Option one: Linked artifact
When using a Bicep template file, you MUST select this option as it is the only one that works
Specifying this option means your Bicep file and optional JSON parameters file are either included in your linked code or can be pulled in as build artifacts
When using this option you must specify the path to your template with csmFile and, optionally, you can also specify the path to your JSON parameters file or .bicepparam file with csmParametersFile
Option two: URL of the file
This option does NOT work with Bicep deployments
Select this option if your template and optional parameters file are located at an http/https URL
You must specify the URL to your template with csmFileLink and, optionally, you can also specify the URL to your JSON parameters file or .bicepparam file with csmParametersFileLink
overrideParameters
This let's you provide parameter values to your Bicep template via the Azure DevOps Pipelines task. This gives you the benefit of being able to use Pipeline variables and/or Pipeline parameters
This is specified as a single string value, but you can include multiple different parameters in the same string. For example: overrideParameters: '-key1 value1 -key2 value2'
Parameter values entered this way take precedence over values supplied with a parameters file.
This is optional. Either your deployment doesn't need parameters or you're supplying parameters in a different way
deploymentOutputs
If your Bicep file defines any Outputs, then you should use this option. Give it a value and it will create a new Pipeline variable by that name which includes all of the Outputs from your Bicep deployment. You then use the Pipeline variable in later steps of your Pipeline
The new variable will contain data in JSON form, so you must process it accordingly. PowerShell's ConvertFrom-Json command works great here
This is optional. Either your deployment doesn't have any Outputs or you don't want to store them in a Pipelines variable
addSpnToEnvironment
If you set this to true then you will have access to 2 new variables that you can use within the overrideParameters section:
$servicePrincipalId
$servicePrincipalKey
These are just as they sound, and give you secure access to the Id and Key of the Azure DevOps Service Connection being used to run this task
This is optional. If omitted, the default option of false is used
Examples of minimal deployment commands
Well, that covers most of the basics of deploying Bicep files with the ARMTemplateDeployment task for Azure DevOps Pipelines.
The next part in this series will cover deploying Bicep files using the Arm-Deploy GitHub Action.
My Bicep Deployment series:
Part 2 - Deploying Bicep with AZ CLI
Part 4 - You're reading it now!
Extra Credit - My Advanced Bicep Guide
Comments