Hey, you. You’re not manually deploying your Azure Bicep Infrastructure as Code, are you?!? Let’s prevent that next production outage, help your team collaborate on changes, and enable more frequent deployments. In this post, I’ll outline what tooling is available to integrate Bicep in your pipelines, and some good practices for building and deploying.
Resources to get started
If you’re new to Azure Bicep, I’d recommend checking out the Microsoft Learn learning path for Bicep. There are also great resources for the basics on Deploying Bicep files by using GitHub Actions and Integrating Bicep with Azure Pipelines. Once you have the fundamentals covered, you may find the remainder of this post helpful.
Build
Tooling
I’m going to break things down into 2 phases of the pipeline: 1. build 2. deploy. For the build phase, we have multiple options for tooling:
- Bicep CLI โ now included in Azure Pipelines Microsoft-hosted agents and GitHub Actions hosted runners. You can also add script steps to install on self-hosted agents based on OS.
-
Azure CLI โ Bicep is now included in v2.20.0 or later. Installing Bicep is as simple as running
az bicep install
- Bicep GitHub Action – Action built and maintained by a community member.
- Bicep extension for Azure Pipelines – Set of Azure Pipeline tasks built and maintained by a community member.
Good Practices
I like to set up the build phase early in my pipeline, in order to fail fast and speed up the feedback loop. The build should make sure 3 things happen:
- Ensure transpilation (conversion to ARM template) is successful.
- Ensure linting rules pass. Configure bicepconfig.json to throw an error on important rule violations.
- Ensure preflight validaton is successful.
To combine all of the above using a single command, validation commands can be used. For a resource group deployment, I can use the Azure CLI command az deployment group validate
or Azure PowerShell’s Test-AzResourceGroupDeployment.
For an example of this using GitHub Actions, check out my SpaceGameVNext’s pipeline here.
Deploy
Tooling
Similar to build, we have multiple options for deployment:
- Azure CLI โ no install needed v2.20.0 or later. I can issue a deployment command pointed at a Bicep template and Bicep will be downloaded and installed on the fly, behind the scenes.
- Azure PowerShell โ Unfortunately Azure PowerShell doesn’t automatically install the Bicep CLI. Instead, you must manually install the Bicep CLI.
- Deploy Azure Resource Manager (ARM) Template GitHub Action – Action built and maintained by Microsoft Azure. Now supports Bicep.
- ARM template deployment Azure Pipeline task – Official Azure Pipeline task. No native Bicep support. Requires referencing transpiled ARM Template.
Good Practices
I like to promote the same set of templates for all environments (dev -> test -> prod). This encourages the DRY (Don’t repeat yourself) principle. In order to make this happen, I can:
- Use conditions on resources that may differ. For example, if I only want to use deployment slots in production.
- Use ternary expressions on properties that differ. For example, if I want to use different storage account SKU’s.
- Leverage pipeline environment variables to re-use same steps for each environment.
Additionally,
- Do not store secret values in templates. If you use Key Vault, check out Use Azure Key Vault to pass secure parameter value during Bicep deployment.
- Use what-if to preview changes. This is a great way to review the impact your changes will have via dry-run.
- Cleanup dev/test environment resources when no longer needed. I like to have a separate pipeline that get’s triggered on the merge of PR, that destroy’s resources that were created for the sole purpose of testing that PR’s change.
For an example of this using GitHub Actions, check out my SpaceGameVNext’s pipeline here.
Summary
None of this is hard and fast guidance to follow strictly. There are many different types of architectures, environments, repository structures, etc. These are things that I’ve found success with and YMMV. What have you found success in while integrating Bicep into your pipelines? I would love to hear your thoughts in the comments.
This is a great blog post Marcus, thanks for posting!
I tend to use the CLI tasks for my deployments (Iโve been using your repo mentioned above as a starting point) and it works really well
Few questions if I may:
1) What are your opinions on testing the templates, is there a tool similar to the ARM-TTK coming for bicep? Testing for things like out of date API versions etc
2) I like the subscription scope deployment, but doing it that way means missing out on switching from incremental/complete modes when needed, to remove resources that are no longer in the template, like you can do with a RG scope. Is something like that coming soon?
Thanks
Thanks, Paul!
1. The Bicep linter shifts more validations left, into VS Code while you’re authoring templates. We’re working to meet parity with all of the arm-ttk tests that make sense. We’ve had quite a few ideas submitted for linting rules (see here). Beyond IDE tests, I’d recommend leveraging pre-flight validation and what-if, as mentioned above.
2. The ARM Deployments team is working on a new feature called Deployment Stacks that will improve resource lifecycle management. It should be in private preview soon!
Thanks for replying Marcus, Iโm just going to stick with the linter now then as it works a treat so far
Iโm looking forward to testing out deployment stacks. I can imagine more people are moving towards subscription scope deploys now, so this will prove very useful!