Azure Resource Deployment with Bicep

DataFairy
6 min readFeb 6, 2022

--

The good, the bad and the ugly?

After spending a couple of days experimenting with the new Bicep format/language (?) for Azure resource deployments I get the feeling there is a lot to talk about. So let’s start with a “short” introduction:

Deploying Azure resources can be done in a couple of different ways. If your have the “Contributer” role within a resource group in an Azure subcription you can directly create resources using the + button in the Azure portal. Another way is using the terminal with either the az cli or Powershell. All these methods are based on resource templates and parameter files which are called ARM templates (Azure Resource Manager). Once you have such a template you can upload it to Azure and create a new resource such as storage accounts, key vaults, VM’s etc.

ARM templates have been the standard when working with the infrastructure as code method. What I have been doing for the last couple of years to get my hands on ARM templates is to “create” resources in the portal, get to the review section of the process and download the base templates. These templates then get moved to a repository (Azure DevOps) where I can create standard pipelines to run custom builds that create those resources. It’s probably not the fastest way but one of the easiest to get your hands on the templates that you need.

ARM template for a storage account

Some weeks ago the Azure team introduced a new domain specific language (DSL) called Bicep that uses a declarative syntax to deploy Azure resources.

Bicep provides concise syntax, reliable type safety, and support for code reuse.

Bicep template for a storage account

To be totally honest, ARM templates are not the prettiest sight and they feel pretty rigid to work with. They require a good understanding of the resources themselves to be readable and are very limited when it comes to specific configurations such as resource locks or role assignments.

When working with Bicep I was pleasantly surprised that I can not only read them with less “domain” knowledge ( I do have years of experience working in Azure though), reuse variables within one deployment and incorporate actions I would normally use the az cli for.

So let’s get into the Bicep review:

PROS

  • Language feel: Bicep is not just a new template for deploying resources but it also is a DSL. Working with Bicep feels like writing code, it has modules, main deployment files and reusable variables.
  • Readability: Once you have a deployment set up it can look clean and readable. Every resource can be put in it’s own module file. Parameters live in a parameter file and the main deployment is another file where all of it comes together.
  • Reusable variables: When creating a module for a resource I can directly use the variables defined in my parameter file with something similar to an import statement. Modules also have outputs which can be used to return values such a resource id to be reused by another module.
Those parameters are then defined in the parameters file
This output can be then reused by other resources
  • VSCode integration: When working with Bicep and VSCode I made heavily use Bicep extensions that would check if my deployment files were valid and if they had missing/wrong dependencies. I could validate my syntax with VSCode.
  • More options: Compared to ARM templates, Bicep offers more configuration options for resources in one deployment. Adding locks to resources, adding role assignments and using secrets from an existing Key Vault are just a few examples I managed to do in a Bicep deployment without the help of az cli, Powershell or the Azure Portal.
  • Loops: Bicep gives us the option to use for loops. For example you can add multiple access policies to a Key Vault defined in your parameters files within one statement.
For loop in a Bicep module with storage accounts
  • Dependencies: You can deploy resource with conditions like dependsOn or existing. Those give you the option to not deploy resources if other resources are not deployed yet or do not exist.
This VM depends on a NIC, Key Vault and VNet to be deployed first
  • @allowed: In Bicep you can use the @allowed keyword to only allow certain configurations for specific resources.
Restricting the replication options for a storage account

CONS

  • One thing that has become quite clear to me when working with Bicep is that the learning curve is quite steep. It helps to dig through some example deployments done by other bloggers especially when deploying multiple resources with dependencies.
  • Bicep is still pretty new and if you decide to move from ARM to Bicep, you might be the first one in your company. You might have to create a Bicep library from scratch.
  • To be able to work with Bicep instead of ARM and create Infrastructue as Code really means you need to create another code repository that is based on Bicep deployments. It probably requires days of coding if there is no reliable out-of-the-box converting system for ARM to Bicep.
  • Bicep is not yet a full replacement for az cli/powershell as not all configurations can be done with Bicep. It’s definitely better than ARM but you will still have to run commands in terminal to for example create secrets in key vault.
  • Bicep is based on ARM templates, it’s an abstraction layer. If you didn’t like ARM, you won’t be off the hook with Bicep. The ARM structure is still visible in a Bicep module.
  • Error messages can be cryptic. I was missing some configuration in a Network Interface I wanted to deploy and all I got was Bad Request. I fixed it by going through the ARM template that was necessary for the deployment but it took me quite a while to find the error.
  • Inconsistencies: Linux VM’s with ssh authentication that requires a password in Bicep but not in ARM, having to call APIs before they are even initialised, Bicep isn’t working perfectly yet. Sometimes you will have to find “diy fixes” to make deployments work.

UGLY

The last point I want to make is how frustrating it can be to get your hands on a bicep file. With ARM, as mentioned before, I can download the “raw” template and parameter file from the Azure Portal. With Bicep I would have to either use a converter, or map it myself. And with mapping I mean, first get the full bicep module for a resource (which can be hundreds of lines of code), check what I need in my ARM and remove everything else from the Bicep file.

This can take hours when you are not familiar with the resources or just starting out. But as far as I have seen this is still the best option for custom deployments.

Final Words

After working with Bicep for a while I think it is a great improvement to ARM templates. Instead of just dumping templates and updating parameters, Bicep gave me much more of a coding experience. If it includes more options to configure resources in Azure it would be a great tool to fully work with infrastructure as code. The Bicep playground is a great way to get simple templates. Also try out the Azure Bicep code library. When looking at how much documentation and blogs there are it shouldn’t be too difficult to get started.

With room for improvement, Bicep is a great tool to deploy Azure resources and worth switching to.

If you found this article useful, please follow me.

--

--

DataFairy

Senior Data Engineer, Azure Warrior, PhD in Theoretical Physics, The Netherlands. I write about Data Engineering, Machine Learning and DevOps on Azure.