Streamlining developer experience with Private Bicep Repositories

In the world of Azure and cloud infrastructure management, a top priority is consistently ensuring a clear and robust Azure governance and policy enforcement.

Within this context, we encounter two primary concepts, Azure Policies and Private Bicep Repositories, each offering unique advantages in shaping the parameters and limitations of your cloud environment. This is an important best practice in defining a clear rulebook for all the teams contributing to your IT landscape and cloud environment.

While Azure Policies facilitate the enforcement of governance and compliance regulations across your Azure resources to ensure alignment with your organization’s global rulebook, a Private Bicep Repository approach takes a proactive stance by implementing these rules at the very base of your infrastructure as code (IaC) implementation.

This blog post will provide a step-by-step guide to create a Private Bicep Repository, automating and versioning private bicep modules and facilitating access to these modules for diverse consumer groups.

Advantages of Private Bicep Repositories:

Using Private Bicep Repositories offer several advantages in the context of Infrastructure as Code and Bicep, a domain-specific language for deploying Azure resources.

– Governance: enforce your Azure governance by applying conventions (such as naming conventions, pricing tier regulations, region restrictions, …) as part of your private bicep module definition
– Parameterization: grant flexibility to your module consumers through parameterization, while still enforcing the hard restrictions defined by your governance
– Isolation: by using a private repository, you can isolate the bicep module definition and version management using a centralized approach while still providing reusability to your different consumer groups
– Version Control: version control is crucial in infrastructure as code to track changes, roll back to previous configurations and ensure consistency.
– Collaboration Control: Grant limited access and control to specific team members authorized to modify your infrastructure bicep modules.

Creating a repository structure

We’ll be making use of the following repository structure:

– /
………– deployment : this directory will contain deployment scripts
………– infra : this directory will contain initial setup for the container registry
………– src
………………– microsoft : this will contain the initial public bicep modules
………………– facade : this directory will contain a façade that will already enforce certain best practices
………………– customers : this directory will contain customer-specific module configuration
………– usage-sample : this directory will contain a single bicep file that will pull and use a module from the container registry

Making use of the Azure Resource Modules Github repository

We’re going to make extensive use of the modules Microsoft has provided the public.

First we’ll clone the repository to a private location.
Run the following command:

$>git clone

Then we move the cloned modules under our own repository structure.

From here on out, this repository will make up a part of our own private solution, so we have full control over it.

Deploying the container registry

Since we’re already working with bicep, we might as well deploy the Azure Container Registry via a bicep module. We’ll provide the bicep template itself and the Azure CLI commands to deploy it in this article.

We will be assuming the container registry module we cloned from the Github repository earlier is located under the following path: /src/Microsoft/compute/container-registry/main.bicep

First we create the bicep template under “/infra” :

Then we’ll deploy it using Azure CLI with the following commands:

$> az login
$> $resourceGroup = “myresourcegroupname”
$> $subscriptionId = “mysubscriptionid”
$> $templateFilePath = “./infra/containerregistry.bicep”
$> az deployment group create –resource-group $resourceGroup –subscription
$subscriptionId –template-file $templateFilePath

For demo purposes we are using hard coded values in the bicep file, however this can be optimized by using parameters.

Manage and release private bicep modules

We’ll add façade modules appending the “_v1.0” suffix under /src/facade

The façade module can be used to enforce naming conventions which we want to apply, or enforce specific pricing tiers by reducing the properties in the @allowed attribute for the given parameter.

Underlying, the façade module is referencing the default Microsoft-bicep module which we added to our git repository:

module storageAccounts ‘../Microsoft/storage/storage-account/main.bicep’

We’ll be using a powershell script to deploy our bicep modules to the container registry, implementing version control:

The powershell script applies logic on the naming convention of the bicep files to define the container repository name and version which is released to the azure container registry.

Reference and consume the private bicep repository

First, create a bicepconfig file, which should reside inside of your consumer repository. It should contain a module alias like so:

Then, create a bicep module referencing this container registry alias:

And finally, deploy this module:

$> az login
$> $resourceGroup = “myresourcegroupname”
$> $subscriptionId = “mysubscriptionid”
$> $templateFilePath = “./usage-sample/main.bicep”
$> az deployment group create –resource-group $resourceGroup –subscription
$subscriptionId –template-file $templateFilePath


Using these scripts you can deploy versioned bicep modules, implement governance and maintain control.

We hope you enjoyed reading this article, learning about Azure Container Registry and how to use it in combination with bicep modules to your advantage.

– Cedric Denoo

Other .insights