top of page
Search

Deploying Bicep Files Part 4 - Azure DevOps Pipelines

Writer's picture: NathanNathan

Updated: Feb 8

 

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. Support for Bicep parameter files was added as of version 3.235.0. 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. If you'd like more information on that subject, please see my series on Azure DevOps YAML Pipelines.


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.


Finally, this task does not support Deployment Stacks.


 

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

  • ConnectedServiceName

    • 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 azureResourceManagerConnection

  • subscriptionName

    • Enter in the Subscription name that contains the Resource Group that you are deploying to.

    • An alias that can be used in place of this is subscriptionId

    • This is optional if you also specify a ConnectedServiceName that is scoped to a Subscription. In that case, if subscriptionName is omitted, the default value that will be used is the Subscription that is configured on your Azure DevOps Service Connection

    • If your chosen ConnectedServiceName is scoped to a Management Group, then subscriptionName 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

  • ConnectedServiceName

    • 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 azureResourceManagerConnection

  • subscriptionName

    • Enter the Subscription that you are deploying to

    • An alias that can be used in place of this is subscriptionId

    • This is optional if you also specify an ConnectedServiceName that is scoped to a Subscription. In that case, if subscriptionName is omitted, the default value that will be used is the Subscription that is configured on your Azure DevOps Service Connection

    • If your chosen ConnectedServiceName is scoped to a Management Group, then subscriptionName 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

  • ConnectedServiceName

    • 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 azureResourceManagerConnection

    • 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 ConnectedServiceName 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

  • useWithoutJSON

    • By default, individual output values are being converted via JSON.Stringify. If you want to use the output values as-is, without converting them via JSON.Stringify, then enable this option

  • 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



 

Deployment Stacks


This task does NOT support creating Deployment Stacks.


 

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 GitHub Action called bicep-deploy.


 

My Bicep Deployment series:


 
 

Comments


bottom of page