Module können nicht über Repository-Grenzen wiederverwendet werden? Eine Bicep-Registry veröffentlichen
Der CloudTrips-Speicher-Wrapper ist innerhalb dieses Repositorys
wiederverwendbar, aber ein anderes Repository kann
./modules/storage.bicep nicht referenzieren. Das Kopieren der Datei erzeugt
getrennte Versionen, die auseinanderlaufen, Korrekturen zu unterschiedlichen
Zeitpunkten erhalten und keinen gemeinsamen Eigentümer mehr haben.
Veröffentliche den Wrapper in einer privaten Bicep-Registry. Eine Bicep-Registry ist eine Azure Container Registry (ACR), die kompilierte Bicep-Module als versionierte OCI-Artefakte speichert. Andere Repositorys können eine genehmigte Version abrufen, ohne den Quellcode zu kopieren.
Diese Registry unterscheidet sich von der öffentlichen Registry der Azure Verified Modules: AVM enthält von Microsoft gepflegte Module, während die private Registry CloudTrips-Module und -Konventionen enthält.
Dieser Trip baut auf folgendem Trip auf: Azure Verified Modules verwenden. Schließe ihn zuerst ab, da dieses Lab den dort entstandenen CloudTrips-Storage-Wrapper versioniert veröffentlicht.
Registry-Infrastruktur erstellen
Die Registry benötigt eine gemeinsame Ressourcengruppe und eine ACR. Erstelle
in cloudtrips-bicep/registry/registry.bicep die Ressourcengruppe und rufe ein
Modul mit Ressourcengruppen-Gültigkeitsbereich auf:
targetScope = 'subscription'
param location string = deployment().location
param resourceGroupName string = 'rg-cloudtrips-bicep-registry-weu'
param registryName string = 'crctbicep${uniqueString(subscription().id)}'
var commonTags = {
Application: 'CloudTrips'
Environment: 'Shared'
ManagedBy: 'Bicep'
Purpose: 'BicepModuleRegistry'
}
resource registryResourceGroup 'Microsoft.Resources/resourceGroups@2025-04-01' = {
name: resourceGroupName
location: location
tags: commonTags
}
module moduleRegistry './registry-resource.bicep' = {
name: '${deployment().name}-registry'
scope: registryResourceGroup
params: {
location: location
registryName: registryName
tags: commonTags
}
}
output registryId string = moduleRegistry.outputs.registryId
output registryName string = moduleRegistry.outputs.registryName
output registryLoginServer string = moduleRegistry.outputs.registryLoginServer
output storageModuleTarget string = 'br:${moduleRegistry.outputs.registryLoginServer}/bicep/modules/storage-account:1.0.0'
Erstelle cloudtrips-bicep/registry/registry-resource.bicep:
param location string = resourceGroup().location
param registryName string
param tags object = {}
resource moduleRegistry 'Microsoft.ContainerRegistry/registries@2025-11-01' = {
name: registryName
location: location
tags: tags
sku: {
name: 'Basic'
}
properties: {
adminUserEnabled: false
anonymousPullEnabled: false
dataEndpointEnabled: false
policies: {
azureADAuthenticationAsArmPolicy: {
status: 'enabled'
}
}
publicNetworkAccess: 'Enabled'
roleAssignmentMode: 'AbacRepositoryPermissions'
zoneRedundancy: 'Disabled'
}
}
output registryId string = moduleRegistry.id
output registryName string = moduleRegistry.name
output registryLoginServer string = moduleRegistry.properties.loginServer
Der Registry-Name wird aus der Abonnement-ID abgeleitet, weil ACR-Namen global eindeutig sein müssen. Die Basic-SKU reicht für diese Lern-Registry aus. Das Administratorkonto und anonymer Pull sind deaktiviert; Identitäten authentifizieren sich über Microsoft Entra ID.
publicNetworkAccess: 'Enabled' bedeutet, dass authentifizierte Clients die
Registry über ihren öffentlichen Azure-Endpunkt erreichen können. „Private
Registry“ beschreibt die Zugriffssteuerung und nicht die Netzwerkisolation.
Ein Produktionsdesign kann eine Premium-Registry mit privatem Endpunkt
verwenden, wenn Netzwerkisolation erforderlich ist.
Erstelle cloudtrips-bicep/registry/registry.bicepparam:
using './registry.bicep'
param location = 'westeurope'
param resourceGroupName = 'rg-cloudtrips-bicep-registry-weu'
Registry anzeigen und bereitstellen
Wähle in cloudtrips-bicep das Abonnement aus, dem die gemeinsame Registry
gehören soll:
az account set \
--subscription "<Name oder ID des CloudTrips-Abonnements>"
Validiere die Bereitstellung und zeige die Vorschau an:
az deployment sub validate \
--location westeurope \
--name validate-cloudtrips-bicep-registry \
--parameters registry/registry.bicepparam \
--validation-level Provider
az deployment sub what-if \
--location westeurope \
--name preview-cloudtrips-bicep-registry \
--parameters registry/registry.bicepparam
Die Vorschau soll eine Ressourcengruppe, eine verschachtelte Bereitstellung und eine Basic-Container-Registry erstellen. Stelle sie bereit:
az deployment sub create \
--location westeurope \
--name deploy-cloudtrips-bicep-registry \
--parameters registry/registry.bicepparam \
--query "properties.outputs" \
--output yaml
Kopiere die Ausgaben registryName, registryLoginServer und
storageModuleTarget.

Zugriff zum Veröffentlichen und Wiederherstellen gewähren
Öffne die neue Container Registry im Azure-Portal und wähle Access control (IAM) > Add role assignment.
Diese Registry verwendet RBAC Registry + ABAC Repository Permissions:
- Gib der Person oder Pipeline, die Module veröffentlicht, die Rolle Container Registry Repository Writer.
- Gib Consumer-Identitäten und Bereitstellungspipelines die Rolle Container Registry Repository Reader.
- Füge Container Registry Repository Catalog Lister nur hinzu, wenn eine Identität alle Repositorys der Registry auflisten muss.
Die Azure-Abonnementrolle Contributor oder Owner ersetzt diese Repository-Datenebenenrollen nicht. Warte nach einer neuen Rollenzuweisung einige Minuten, bevor du veröffentlichst.
CloudTrips-Speichermodul veröffentlichen
Setze die Ausgabewerte in der aktuellen Shell:
registry_name="<registryName-Ausgabe>"
registry_login_server="<registryLoginServer-Ausgabe>"
Veröffentliche den Wrapper mit seinem Quellcode:
az bicep publish \
--file modules/storage.bicep \
--target "br:${registry_login_server}/bicep/modules/storage-account:1.0.0" \
--with-source
Bicep kompiliert das Modul vor der Veröffentlichung. Das Artefakt enthält die
bereitstellbare ARM-Vorlage, während --with-source für Consumer außerdem
Go to Definition in der Bicep-Erweiterung von VS Code ermöglicht.
Bestätige die Version:
az acr repository show-tags \
--name "$registry_name" \
--repository bicep/modules/storage-account \
--output table
Das Ergebnis soll 1.0.0 enthalten. Du kannst auch die Registry öffnen und
Services > Repositories > bicep/modules/storage-account wählen.

Behandle eine veröffentlichte Version als unveränderlich. Verwende nicht
--force, um 1.0.0 zu ersetzen, nachdem Consumer davon abhängen.
Veröffentliche eine Korrektur als 1.0.1, eine kompatible Funktion als
1.1.0 und eine inkompatible Parameter- oder Ausgabeänderung als 2.0.0.
Modul aus einem anderen Repository wiederherstellen
Verwende für dieses Lab den enthaltenen Ordner
cloudtrips-bicep/registry-consumer als separates Consumer-Projekt.
Erstelle oder aktualisiere im Consumer-Repository bicepconfig.json. Ersetze
den Registry-Wert durch den kopierten Login-Server ohne https://:
{
"moduleAliases": {
"br": {
"cloudtrips": {
"registry": "<registry-name>.azurecr.io",
"modulePath": "bicep/modules"
}
}
}
}
Der Alias verkürzt den vollständigen Registry-Pfad. Erstelle im Consumer eine
Datei main.bicep:
param location string = resourceGroup().location
module storage 'br/cloudtrips:storage-account:1.0.0' = {
name: '${deployment().name}-storage'
params: {
applicationName: 'CloudTrips'
containerNames: [
'reports'
]
costCenter: 'CC-DATA-200'
deployAuditContainer: false
environment: 'dev'
location: location
owner: 'CloudTrips Data Team'
storageSku: 'Standard_LRS'
}
}
output storageAccountName string = storage.outputs.storageAccountName
output blobEndpoint string = storage.outputs.blobEndpoint
Melde dich mit einer Identität an, die Container Registry Repository Reader besitzt, und stelle das Modul wieder her:
az bicep restore \
--file main.bicep \
--force
az bicep lint \
--file main.bicep
restore lädt Version 1.0.0 in den lokalen Bicep-Cache. Verwende Go to
Definition auf der Modulreferenz, um den mit dem Artefakt veröffentlichten
Quellcode zu sehen.

Das Consumer-Repository enthält jetzt nur die Modulreferenz und seine eigenen
Parameterwerte. Eine neu veröffentlichte Modulversion ändert den Consumer nicht
unerwartet, da er auf 1.0.0 fixiert bleibt, bis sein Eigentümer die Referenz
prüft und aktualisiert.
Pipeline-Identitäten benötigen ebenfalls Container Registry Repository
Reader und müssen sich vor restore, Linting, Build oder Bereitstellung bei
Azure authentifizieren, damit sie ein privates Modul herunterladen können.
Öffentliche AVM-Referenzen benötigen diese zusätzliche Authentifizierung für
die private Registry nicht.