I have been working with Azure Bicep quite a bit recently and found that community sharing and pipeline consumption of modules is quite challenging and a bit of burden to manage. Pipeline consumption especially so, as we need to ensure all modules are available in our deployment artefacts and our deployment templates contain the correct dynamic pathing to them.
The latest release of Bicep (v0.4.1008) has introduced a new feature that solves this problem, the ability to store and reference Bicep modules from a private container registry. Public registries will be coming in a future release.
In order to utilise this feature we will need an Azure Container Registry, if you don’t have one you can create one by following the instructions here.
Once we have a container registry, we can publish our Bicep modules using the publish command. When using a container registry we have the ability to use tags for our modules, this is a great feature as it enables us to run multiple versions of a module.
NOTE: The account running the publish command will need at least AcrPush access to the Azure Container Registry.
The example below publishes a Storage Account Bicep module to an Azure Container Registry with tag v0.1.
az bicep publish storage.bicep --target br:arincodemo.azurecr.io/bicep/modules/storage:v0.1
NOTE: Currently to be able to utilise the publish and restore commands we must use them directly with the Bicep CLI. This will be rectified in a future release of Bicep as stated here.
Once published we can find our Bicep module in the container registry repository.
As per below.
To utilise a Bicep module inside a container registry we specify the module path with the following syntax:
module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
Example below.
param deploymentName string = 'storage${utcNow()}'
module storage 'br:arincodemo.azurecr.io/bicep/modules/storage:v0.1' = {
name: deploymentName
params: {
storageAccountName: 'arincodemostorage01'
storageSku: 'Standard_LRS'
storageKind: 'StorageV2'
storageTier: 'Hot'
deleteRetentionPolicy: 7
}
}
NOTE: In order to utilise a Bicep module within a container registry the account running the deployment will need at least AcrPull access to the Azure Container Registry.
When referencing a module in a container registry you may find that the path can be quite long. Instead of providing the full path we can configure aliases to make things easier. To do so we add settings to the Bicep config file.
Example below.
{
"moduleAliases": {
"br": {
"ArincoDemoAcr": {
"registry": "arincodemo.azurecr.io"
},
"MgtModules": {
"registry": "arincodemo.azurecr.io",
"modulePath": "bicep/modules/mgmt"
}
}
}
}
When specifying a module path with an alias we use the following syntax:
module stgModule 'br/ArincoDemoAcr:bicep/modules/storage:v0.1' = {
Example below.
param deploymentName string = 'storage${utcNow()}'
module storage 'br/ArincoDemoAcr:bicep/modules/storage:v0.1' = {
name: deploymentName
params: {
storageAccountName: 'arincodemostorage01'
storageSku: 'Standard_LRS'
storageKind: 'StorageV2'
storageTier: 'Hot'
deleteRetentionPolicy: 7
}
}
We can also add module paths our aliases to further simplify our module path by using the following syntax:
module stgModule 'br/MgtModules:storage:v0.1' = {
Example below.
param deploymentName string = 'storage${utcNow()}'
module storage 'br/MgtModules:storage:v0.1' = {
name: deploymentName
params: {
storageAccountName: 'arincodemostorage01'
storageSku: 'Standard_LRS'
storageKind: 'StorageV2'
storageTier: 'Hot'
deleteRetentionPolicy: 7
}
}