Search
  • Nathan

Deploying Bicep Files Part 4 - Azure DevOps Pipelines

Updated: Aug 27

If you haven't already, please check out the previous parts of this series.


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 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 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:

187 views