There’s a few different options when it comes to consuming Bicep modules, do you need to write your own modules? Use the public Bicep registry? or are there other options to consider?
I’ll detail my experiences & thoughts on this with pros & cons that each of the routes have.
To check these different approaches out you can head over to the Bicepify GitHub project to see more:
Public Bicep Registry
Microsoft have recently started publishing Bicep modules on the public registry, this means you can consume the modules directly from VSCode like so:
- Less Bicep engineering and management overhead as you won’t need to create, manage or update the modules (except the API versions in the module block)
- Centrally accessible to everyone
- Easy to view available Bicep modules from the Intelisense
- All parameters included (with descriptions when hovering over the param!). Easy to ‘pick up and go’ and accelerate your Bicep journey
- Azure best practice is baked in to the code by default (although this won’t necessarily stop you deploying with sub-optimal config or misconfigurations)
- Can lag behind latest releases whilst Microsoft update API versions and available Azure resources for the modules
- Bicep Module list is lacking. Many modules are still to be added. But being increased week by week!
- Less flexibility. Can’t be customised as these are centrally controlled by Microsoft
Private Bicep Registry
Like the Bicep public registry, you can create an internal (private) Bicep registry with an Azure Container Registry, to have an internal bicep registry for use. Some great info in the docs on how to get started: Create private registry for Bicep module – Azure Resource Manager | Microsoft Learn
Example private Bicep ACR, note the
br: address is pointing to the ACR manifest URI for that particular module.
br: ACR URI address by editing your bicepconfig.json. e.g. ‘br:bicepify/modules/logging:2023-09-29’ would be an example alias of the below.
- Flexibility of what modules are available for consumption (including custom modules)
- Updating to new API versions, new Bicep modules and any updates are likely to be faster than the public registry alternative
- Security. You control the ACR access and therefore who can use the modules.
- Brings your modules under central control and helps reduce code drift from static module files in repositories differing from organisation standards
- Overhead of managing the registry
- Version control is very important. Breaking changes could have a large knock on impact if not communicated to teams, and could break deployment code across the board
- More suited to larger organisations due to management overhead, testing and custom requirements
- Bicep VSCode Intelisense does not load available modules like the public registry can. This means you have to manually go to the Azure Container Registry and copy the manifest URI to use (Bicep team working on this one, coming before end of the year hopefully)
Inline Bicep modules
Next up is one of the last module consumption options to consider. Using modules in-line, with a structure very much like my blog post on testing Bicep modules.
In the inline Bicep module, we are calling from a local modules folder when writing in our
main.bicep file (seen below) which could be a mixture of your own Bicep modules (custom), or from the below ResourceModules GitHub (see further below) forked. Example:
Example folder structure of this method. Modules are stored in the folder locally in the repository & called from the main file:
│ ├── storageAccount/
│ │ ├── storageAccount.bicep
│ │ ├── metadata.json
│ │ └── README.md
│ └── .tests/
│ └── storageAccount.tests.bicep
- A lot of the pros are very much applicable from the private bicep registry above to this module method
- All modules in one place, easy to understand the code flow and where the module code is, to read and understand it’s parameters, settings and properties
- Great in combination with public registry options where less control and customisation is needed as a half way house option
- Code drift. If you’re an MSP and spinning up lots of customer repositories for deployments, code can drift from updates to your ‘gold standard’ templates / modules. This can make it difficult to keep on top of keeping a 1:1 relationship with the module consistency across environments
- Overhead. Keeping up with updates from the ResourceModule GitHub (below) and general API & resource updates becomes manual
ResourceModules Bicep GitHub (CARML)
Lastly, worthy of it’s own section this one. There is already a large repository for Bicep modules for consumption in the ResourceModules (aka CARML – Common Azure Resource Modules Library) repository, where many modules exist already:
Even if you just need a start point to then customise from. This is a solid bet as you know you’re starting from a good place (best practice baked in).
The Bicep team are looking to move more and more of these modules into the public registry for use which will mean you can pivot to the public registry over time.
Azure Verified Modules (AVM)
This is still in developement at the time of writing. However, there is a new initiative by the IaC teams at Microsoft to present what good Infrastructure-as-Code looks like. The idea here will be these modules will accelerate teams to deploy with Bicep, using best practice & aligned to the Well-Architected Framework.
Keep an eye on this one!
I’m personally a big fan of the Bicep public registry wherever possible. It removes so much of the negatives and is so easy for writing code, as you can just directly define parameter values in the module block. I currently use a combination of the public registry and in-line modules forked from the ResourceModules repository. This works really well until the public registry gets up to speed.