As part of our blog series on infrastructure as code (IaC), we’re doing a deep dive into various IaC tools to see how they work, as well as their pros and cons. Today, we’re talking about Microsoft Azure’s latest innovation: Bicep. Before we explore where this fits in, it’s useful to first look back at how we got here.
A brief history
Microsoft Azure is built on the notion of “resource providers”. These are separate blocks that handle the lifecycle of a certain set of resource types. For example, the “Microsoft.Compute” resource provider deals with resource management of virtual machines and other compute-based resources.
In the infancy of Microsoft Azure, these resource providers existed completely independently of one another. This meant you had to manually and independently manage each resource type. Applying policies to multiple resources was either not possible, or incredibly awkward. This changed in 2014 with the addition of Azure Resource Manager (or ARM – not to be confused with the processor architecture of the same name). Simply put, this added a unified management API on top of the existing resource providers.
Having a single means to communicate with resource providers offers a lot of advantages, including the application of policies across multiple resources, as well as basic things such as the notion of “resource groups”. A further result is the creation of the ARM templating language. This is a schema that enables you to define your infrastructure in JSON.
However, writing your infrastructure in JSON files turns out to be rather cumbersome! Luckily, in 2020, work started on a new domain-specific language for Azure Resource Manager: Bicep.
Why should I use Bicep?
Compared to ARM templates, Bicep accomplishes the same goals while also being much nicer to work with, though Bicep does have some limitations. Even small things like being able to easily use multiple files and have re-usable components, quickly turn into invaluable features.
But then, I hear you ask, why not just use Terraform? There are a few further advantages of Bicep:
- Bicep closely follows the Azure Resource Manager model – Since Bicep is only a light translation layer to ARM templates, you’re using the same underlying ARM service. Any changes to ARM templates are immediately available in Bicep; you don’t need to wait for updates to the AzureRM Terraform provider. Bicep also integrates with the existing Azure Resource Manager deployment features in the Azure Portal so, for example, you can see your Bicep deployments in the Portal (along with logs, failures etc.)
- It’s a drop-in replacement (almost) for ARM templates – If you’ve already invested heavily in ARM templates, switching to Bicep will require minimal migration. You can even decompile an ARM template into Bicep, and while this isn’t fool-proof, it can get you 90% of the way there. Or, if all your further tooling assumes ARM templates, you can author in Bicep and compile it into an ARM template before consuming as usual
- The developer experience is excellent – Bicep works best in Visual Studio Code with the official Bicep extension (more on getting started below)
There are, of course, some disadvantages:
- As you’ve probably guessed, it only works for Microsoft Azure (we’ll cover IaC tools that work in other clouds later in this series of articles)
- The Azure documentation covers all available resources, but sometimes the detail is a bit thin. There are plenty of example templates available, but sometimes you may need to just create the desired result manually and export the template from the Azure Portal
The final thing to be aware of is that Bicep does not use state files. Instead, when you submit your deployment, Azure Resource Manager works out what changes are needed to make your infrastructure match your submission. To assist with this, there are two “deployment modes”:
- Incremental – The default mode. Resources missing from your code are not changed. This is useful when running different Bicep files against the same subscription
- Complete – Resources missing from your code are deleted. This is similar to Terraform’s default setup
After that, you’re free to structure your Bicep code however you see fit. To help you get started quickly, I’ve created an opinionated Bicep template, which is available on GitHub. This includes support for multiple environments and deployments via Azure Pipelines.
If you’re working with Microsoft Azure, Bicep is an excellent tool for your IaC needs. If you’re currently using ARM templates, then migrating to Bicep is a no-brainer. And even if you’re using Terraform, it’s well worth looking into for the enhanced developer experience and the ability to be more agile, by using the Azure Resource Manager API directly.