Create an Azure Container Registry(ACR) in Azure for Bicep Modules

Sep 22, 2025

Hi and welcome. Today I thought I might brush up on some best practices for Bicep modules and create a little handy guide for reference.

If you’re working with Bicep modules in a professional or enterprise environment, using a private container registry is a best practice for keeping your modules . It ensures immutability, security, and easy consumption of modules across your teams. In this guide, I'll walk through creating an Azure Container Registry (ACR), publishing a basic bicep file to it, and validating the setup.

Why Use a Private Bicep Module Registry?

You might be wondering, why go through all the extra steps of pushing modules into a regisry when I could just store them in Git?

Here are the main reasons:

  • Immutability - Once a module version is published (e.g., v1.0.0), it can’t be changed, ensuring reproducible deployments.
  • Consistency across teams -Multiple projects and teams can consume the same module versions directly from a trusted source.
  • Security & Access Control - You can enforce role-based access and network restrictions using ACR.
  • Better CI/CD integration - Pipelines can automatically publish validated modules, making them instantly available for others.
  • Support for restricted environments - Works well in air-gapped or enterprise setups where direct GitHub access may be limited.

Prerequisites

Before you begin, make sure you have:

  • Logged in to Azure CLI
  • Bicep CLI installed
  • An existing Resource Group in Azure
  • Permissions to push to your ACR

Step 1: Create a Bicep File for Your Registry

Start by creating a Bicep file (e.g., acr.bicep) that defines your Azure Container Registry. This file will contain the configuration for your registry, including its name, SKU, and location.

This file is just a sample file I pulled from the an azure link to create a azure container registry

@minLength(5)
@maxLength(50)
@description('Provide a globally unique name of your Azure Container Registry')
param acrName string = 'acr${uniqueString(resourceGroup().id)}'

@description('Provide a location for the registry.')
param location string = resourceGroup().location

@description('Provide a tier of your Azure Container Registry.')
param acrSku string = 'Basic'

resource acrResource 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = {
  name: acrName
  location: location
  sku: {
    name: acrSku
  }
  properties: {
    adminUserEnabled: false
  }
}

@description('Output the login server property for later use')
output loginServer string = acrResource.properties.loginServer

Step 2: Deploy the Registry

Run the following command in PowerShell or your terminal to deploy your registry:

az deployment group create --resource-group example-resources --template-file acr.bicep --parameters acrName=acrtestingaustraliaeast123

Step 3: Validate Your Registry

Once deployment is complete, check that your registry is available and get the login server URL:

Get-AzContainerRegistry -ResourceGroupName "example-resources" -Name "acrtestingaustraliaeast123"  | Select-Object LoginServer

Step 4: Publish Bicep Modules to the Registry

Now that the registry is ready, you can publish your modules. For example:

az bicep publish --file .\modules\container-registry.bicep --target "br:acrtestingaustraliaeast123.azurecr.io/bicep/modules/acr:v1" --documentation-uri "https://www.contoso.com/exampleregistry.html" --with-source

Notes:

  • The --with-source flag publishes the source code alongside the compiled module.
  • The --documentation-uri parameter links to any additional documentation for your module.

the source parameter publishes the source code

Step 5: Verify in the Azure Portal

To confirm everything worked:

  1. Navigate to your Azure Container Registry in the Azure Portal.
  2. Go to Repositories.
  3. You should see your published module under the path bicep/modules/acr with the tag v1.

Your private Bicep module is now ready to be consumed securely in other deployments!

Step 6: Consume the Module in Another Bicep File

Ok great, now that your module is published, you can reference it in your bicep deployments using the bicep reigstry syntax

What’s happening here?

  • The br: prefix tells Bicep to pull the module from a registry.
  • The path points to your private ACR instance.
  • The version tag (:v1) ensures you always get the exact version you published.
module myAcrModule 'br:acrtestingaustraliaeast123.azurecr.io/bicep/modules/acr:v1' = {
  name: 'acrDeployment'
  params: {
    acrName: 'myNewRegistry'
    location: 'australiaeast'
    sku: 'Basic'
  }
}

Run it with the below command:

az deployment group create --resource-group example-resources --template-file main.bicep

And that's it. Easy as that, you've succesfully deployed an Azure Container Registry for Bicep Modules

What’s next?
From here, you can:

  • Tag and version your modules for better lifecycle management.
  • Integrate them directly into your CI/CD pipelines.
  • Add documentation so your team knows how to use each module.
  • Secure your registry with RBAC to control who can publish and consume modules.
  • And of course, always test thoroughly before pushing to production.

References & Quickstart Links:

Create a private container registry in Azure for Bicep modules - Azure Resource Manager
Learn how to set up a private container registry in Azure for private Bicep modules.
Quickstart - Create Registry - Bicep - Azure Container Registry
Learn how to create an Azure container registry by using a Bicep file.