Anyone trying to deliver quality software has most likely used DevOps pipelines before to build a consistent way to deploy code. This can be to a single production environment, but with minimal configuration to a dozen other environments for development, testing, acceptance, training, A/B testing, … The initial focus of these DevOps pipelines was to build, test and deploy code. But trying to deploy to multiple environments means that you’ll want a consistent way to set up these environments as well. This means other software that has to be installed, configuration of hardware and software, …
For that reason there’s the concept ‘Infrastructure as Code’ which enables coding or scripting your required infrastructure on-premises or in the cloud. There are multiple options if we look at Azure, both from Microsoft (ARM templates, Azure CLI, Azure PowerShell) and third party (Terraform, Pulumi, Ansible, …). But in the end all of them make use of the Azure Resource Manager API to get their work done. Making a choice comes down to choosing an option that has decent support (instead of something exotic) and is in line with your team’s skillset.
What is Azure Bicep?
Bicep is a domain-specific language (DSL) that uses declarative syntax to deploy Azure resources.
For years the primary ARM template tooling from Microsoft were JSON templates. When creating an Azure resource in the portal, you were able to export the JSON template to help your automation or you could write a JSON file yourself. One of the major downsides of ARM templates were the size of the JSON documents, making it cumbersome to edit and maintain.
Microsoft acknowledged this and started working on a DSL called Bicep as the ‘next generation ARM templates’. It builds on top of Azure Resource Manager so anything that can be done in ARM will be supported by Bicep as well. The DSL language and tooling are public on GitHub. Even though the current version is 0.4, it’s officially supported by Microsoft support and completely free to use.
What about my ARM templates
You can use both ARM JSON templates and Bicep side by side, but it might be easier to start decompiling ARM templates into Bicep to have a single technology.
When not to use Bicep
If you’re mainly working with ARM templates before, then Bicep is almost a non-brainer evolution. But there are certainly valid reasons to not use Bicep:
- You’re already using another IaC toolset (e.g. Terraform, Pulumi, …) and you’re team is used to it.
- You’re targeting other platforms than Azure (*).
- Your needs are so specific or very limited that the overhead of using IaC is a too huge cost.
(*): Quite often teams or companies opt a more generic approach to prevent a ‘vendor lock-in’. While this sometimes is a valid choice, it’s more often not. In the context of cloud, the argument often is being able to switch between the major cloud providers. Anyone following ‘cloud’ closely know that competitors do their best to close the gaps, both on missing services and price. Picking a single cloud provider allows you to improve your experience with this platform, getting more out of the available managed services, or simply delivering faster. Note that choosing any IaC toolset, code or technology (e.g. containers) to make you ‘cloud agnostic’ also comes with a (learning) cost and vendor lock-in in that specific toolset.
Learning Azure Bicep
Azure Bicep is (in my opinion) quite easy to get started with. If you have seen or used a DSL like e.g. Terraform before then you’ll get used to it even faster.
In short: follow the official Microsoft Learn Bicep track and you’ll get a solid introduction. I’ve done this myself and was writing Bicep templates for our new project and deploying them within less than a day. Going through the complete course is a good way to learn the basics and evolve that into good practices. But I’ve also added a few interesting links below to take a shortcut in getting started or have as future reference material.
Issues I ran into
Since we’re not at a version 1.0 yet, there are still a few features missing or needing some polishing. The items I ran into are mostly for more complex scenarios (read: where IaC starts to shine, anyone can deploy a single resource).
Validating resource naming rules with the linter, so you get an error in VS Code before actual deployment. Think about resource lengths, invalid characters etc. More info: https://github.com/Azure/bicep/issues/1679
Having a param of type resource to pass newly created resources into other modules. This enables creating more reusable scripts. More info in these issues:
The current Learn materials mainly focus on build pipelines. This however doesn’t mean that we can’t build a release pipeline.
- Bicep GitHub repo
- Bicep documentation landing page
- Bicep learning path
- Bicep twitter
- VS Code Bicep Extension
- Template reference: know what’s available.
If you don’t have time to go throught he complete Microsoft Learn modules (although this takes less than a day even with new modules being added), I advise you to at least check these pages to get quick start:
- Introduction module: The very basics including installation, writing a first script and using parameters and modules (without you won’t get far).
- How to use parameter files: The first step in supporting multiple environments.
- Securing parameters
- Defining child resources