Moduły Bicep

Dzięki aplikacji Bicep można organizować wdrożenia w moduły. Moduł to plik Bicep, który jest wdrażany przez inny plik Bicep. Moduł może być również szablonem usługi Azure Resource Manager (szablon usługi ARM) dla formatu JSON. Korzystając z modułów, można poprawić czytelność plików Bicep, hermetyzując złożone szczegóły wdrożenia. Można również łatwo używać modułów dla różnych wdrożeń.

Aby udostępnić moduły innym osobom w organizacji, utwórz specyfikację szablonu lub rejestr prywatny. Specyfikacje szablonów i moduły w rejestrze są dostępne tylko dla użytkowników z odpowiednimi uprawnieniami.

Tip

Wybór między rejestrem modułów a specyfikacjami szablonów jest głównie kwestią preferencji. Podczas wybierania dwóch opcji należy wziąć pod uwagę następujące kwestie:

  • Tylko Bicep obsługuje rejestr modułów. Jeśli nie używasz narzędzia Bicep, użyj specyfikacji szablonów.
  • Zawartość można umieścić w rejestrze modułów Bicep tylko z innego pliku Bicep. Specyfikacje szablonu można wdrażać bezpośrednio z poziomu interfejsu API, programu Azure PowerShell, interfejsu wiersza polecenia platformy Azure i witryny Azure Portal. Możesz nawet użyć UiFormDefinition, aby dostosować doświadczenie wdrażania portalu.
  • Bicep ma pewne ograniczone możliwości osadzania innych artefaktów projektu (w tym plików innych niż Bicep i innych niż szablon ARM, takich jak skrypty programu PowerShell, skrypty interfejsu wiersza polecenia i inne pliki binarne) przy użyciu funkcji loadTextContent i loadFileAsBase64. Specyfikacje szablonu nie mogą spakować tych artefaktów.

Moduły Bicep są konwertowane na pojedynczy szablon usługi ARM z zagnieżdżonymi szablonami. Aby uzyskać więcej informacji na temat sposobu, w jaki Bicep rozwiązuje pliki konfiguracyjne oraz jak łączy plik konfiguracyjny zdefiniowany przez użytkownika z domyślnym plikiem konfiguracyjnym, zobacz Proces rozwiązywania plików konfiguracyjnych oraz Proces scalania plików konfiguracyjnych.

Definiowanie modułów

Podstawowa składnia definiowania modułu to:

@<decorator>(<argument>)
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

Prosty, rzeczywisty przykład wygląda następująco:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Możesz również użyć szablonu ARM w formacie JSON jako modułu:

module stgModule '../storageAccount.json' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Użyj nazwy symbolicznej, aby odwołać się do modułu w innej części pliku Bicep. Na przykład możesz użyć nazwy symbolicznej, aby pobrać dane wyjściowe z modułu. Nazwa symboliczna może zawierać znaki a-z, A-Z, 0-9 i podkreślenie (_). Nazwa nie może zaczynać się od liczby. Moduł nie może mieć takiej samej nazwy jak parametr, zmienna lub zasób.

Ścieżka może wskazywać na plik lokalny lub plik przechowywany w rejestrze. Plik lokalny może być plikiem Bicep lub szablonem ARM w formacie JSON. Aby uzyskać więcej informacji, zobacz Ścieżka do modułu.

Właściwość name jest opcjonalna. Staje się nazwą zagnieżdżonego zasobu wdrożenia w wygenerowanym szablonie. Jeśli nie podano nazwy, identyfikator GUID zostanie wygenerowany jako nazwa zagnieżdżonego zasobu wdrożenia.

W przypadku wdrażania modułu o nazwie statycznej jednocześnie w tym samym zakresie jedno wdrożenie może zakłócać dane wyjściowe z drugiego wdrożenia. Jeśli na przykład dwa pliki Bicep używają tego samego modułu o tej samej nazwie statycznej (examplemodule) i są przeznaczone dla tej samej grupy zasobów, jedno wdrożenie może wyświetlić nieprawidłowe dane wyjściowe. Jeśli martwisz się o współbieżne wdrożenia w tym samym zakresie, nadaj modułowi unikatową nazwę. Innym sposobem na zapewnienie unikalnych nazw modułów jest pominięcie właściwości name — unikalna nazwa modułu zostanie wygenerowana automatycznie. Reguła no-module-name linter została zaprojektowana tak, aby wymusić tę czystszą praktykę kodowania, flagując dowolny moduł, który nadal zawiera jawną name właściwość.

Poniższy przykład łączy nazwę wdrożenia z nazwą modułu. Jeśli podasz unikatową nazwę wdrożenia, nazwa modułu będzie również unikatowa.

module stgModule 'storageAccount.bicep' = {
  name: '${deployment().name}-storageDeploy'
  scope: resourceGroup('demoRG')
}

Niepodanie nazwy modułu jest również prawidłowe. Identyfikator GUID jest generowany jako nazwa modułu.

module stgModule 'storageAccount.bicep' = {
  scope: resourceGroup('demoRG')
}

Jeśli musisz określić zakres , który różni się od zakresu głównego pliku, dodaj właściwość zakresu. Aby uzyskać więcej informacji, zobacz Ustawianie zakresu modułu.

// deploy to different scope
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  scope: <scope-object>
  params: {
    <parameter-names-and-values>
  }
}

Aby warunkowo wdrożyć moduł, dodaj if wyrażenie. Jest to podobne do warunkowego wdrażania zasobu.

// conditional deployment
module <symbolic-name> '<path-to-file>' = if (<condition-to-deploy>) {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

Aby wdrożyć więcej niż jedno wystąpienie modułu, dodaj for wyrażenie. Użyj dekoratora batchSize, aby określić, czy wystąpienia są wdrażane szeregowo, czy równolegle. Aby uzyskać więcej informacji, zobacz Iteracyjne pętle w Bicep.

// iterative deployment
@batchSize(int) // optional decorator for serial deployment
module <symbolic-name> '<path-to-file>' = [for <item> in <collection>: {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}]

Podobnie jak zasoby, moduły są wdrażane równolegle, chyba że zależą one od innych modułów lub zasobów. Zazwyczaj nie trzeba ustawiać zależności, ponieważ są one określane niejawnie. Jeśli musisz ustawić jawną zależność, dodaj dependsOn do definicji modułu. Aby dowiedzieć się więcej o zależnościach, zobacz Zależności zasobów w aplikacji Bicep.

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
  dependsOn: [
    <symbolic-names-to-deploy-before-this-item>
  ]
}

Ścieżka do modułu

Możesz użyć pliku lokalnego lub pliku zewnętrznego dla modułu. Plik zewnętrzny można znaleźć w specyfikacji szablonu lub w rejestrze modułów Bicep.

Plik lokalny

Jeśli moduł jest plikiem lokalnym, podaj względną ścieżkę do tego pliku. W Bicep należy używać separatora katalogów w postaci ukośnika (/) we wszystkich ścieżkach, aby zapewnić spójną kompilację na wszystkich platformach. Znak ukośnika odwrotnego Windows (\) nie jest obsługiwany. Ścieżki mogą zawierać spacje.

Aby wdrożyć plik znajdujący się o jeden poziom wyżej w katalogu niż plik główny, użyj poniższego przykładu:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Plik w rejestrze

Istnieją rejestry modułów publicznych i prywatnych.

Rejestr modułów publicznych

Note

Moduły zweryfikowane nienależące do platformy Azure zostały wycofane z publicznego rejestru modułów.

Moduły zweryfikowane platformy Azure to wstępnie utworzone, wstępnie przetestowane i wstępnie zweryfikowane moduły, których można użyć do wdrażania zasobów na platformie Azure. Pracownicy firmy Microsoft utworzyli i posiadają te moduły. Upraszczają i przyspieszają proces wdrażania typowych zasobów i konfiguracji Azure. Moduły są również dostosowane do najlepszych rozwiązań, takich jak Azure Well-Architected Framework.

Przeglądaj moduły Bicep, aby zobaczyć listę dostępnych modułów. Wybierz wyróżnione liczby na poniższym zrzucie ekranu, aby przejść bezpośrednio do tego filtrowanego widoku:

Zrzut ekranu przedstawiający moduły zweryfikowane platformy Azure.

Lista modułów zawiera najnowszą wersję. Wybierz numer wersji, aby wyświetlić listę dostępnych wersji.

Zrzut ekranu przedstawiający wersje modułów zweryfikowanych platformy Azure.

Aby połączyć się z publicznym modułem, określ ścieżkę modułu z następującą składnią:

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public: jest to alias dla modułów publicznych. Ten alias można dostosować w pliku konfiguracyjnym Bicep.
  • ścieżka pliku: może zawierać segmenty oddzielone znakiem / .
  • tag: określa wersję modułu.

Przykład:

module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

Note

Alias dla modułów publicznych to br/public. Możesz również napisać go w następujący sposób:

module <symbolic-name> 'br:mcr.microsoft.com/bicep/<file-path>:<tag>' = {}

Rejestr modułów prywatnych

Jeśli moduł został opublikowany w rejestrze, możesz połączyć się z tym modułem. Podaj nazwę rejestru kontenerów platformy Azure i ścieżkę do modułu. Określ ścieżkę modułu z następującą składnią:

module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
  • br: Jest to nazwa schematu dla rejestru Bicep.
  • ścieżka pliku: jest to nazywane repository w usłudze Azure Container Registry. Ścieżka pliku może zawierać segmenty oddzielone znakiem / .
  • tag: określa wersję modułu.

Przykład:

module stgModule 'br:exampleregistry.azurecr.io/bicep/modules/storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Podczas odwołania się do modułu w rejestrze, rozszerzenie Bicep w programie Visual Studio Code automatycznie wywołuje bicep restore, aby skopiować moduł zewnętrzny do lokalnej pamięci podręcznej. Przywrócenie modułu zewnętrznego trwa kilka minut. Jeśli funkcja IntelliSense dla modułu nie działa natychmiast, poczekaj na zakończenie przywracania.

Pełna ścieżka modułu w rejestrze może być długa. Zamiast dostarczać pełną ścieżkę za każdym razem, gdy chcesz użyć modułu, skonfiguruj aliasy w pliku bicepconfig.json. Aliasy ułatwiają odwołanie do modułu. Na przykład za pomocą aliasu można skrócić ścieżkę do:

module stgModule 'br/ContosoModules:storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Rejestr modułów publicznych ma wstępnie zdefiniowany alias:

module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

Alias publiczny można zastąpić w pliku bicepconfig.json .

Począwszy od wersji Bicep CLI 0.43.1 narzędzie Bicep jednoznacznie blokuje korzystanie z domen niestandardowych podczas odwoływania się do modułów lub ich przywracania z rejestru Azure Container Registry (ACR). To zabezpieczenie uniemożliwia korzystanie z nieobsługiwanych konfiguracji, które w przeciwnym razie spowodują problemy ze zgodnością.

Jeśli spróbujesz odwołać się do domeny niestandardowej, takiej jak moduleStore.myCompany.com, interfejs wiersza polecenia Bicep zwróci błąd diagnostyczny BCP446. Przykład:

module foo 'br:moduleStore.myCompany.com/networking/hub:1.0.0' = { ... }

Bicep weryfikuje wszystkie nazwy hostów rejestru względem wbudowanej listy dozwolonych hostów. Obecnie dozwolone są tylko następujące domeny:

  • *.azurecr.io
  • *.azurecr.cn
  • *.azurecr.us
  • mcr.microsoft.com
  • mcr.azure.cn
  • ghcr.io

Jeśli twoja organizacja korzysta z domen niestandardowych, zaktualizuj pliki Bicep w celu zachowania zgodności z następującymi ograniczeniami:

  • Przywróć natywne nazwy hostów: Zaktualizuj wszystkie odwołania do modułu Bicep, aby używać natywnej .azurecr.io (lub odpowiedniej domeny specyficznej dla chmury).
  • Wyczyść lokalną pamięć podręczną: Po zaktualizowaniu referencji może być konieczne wyczyszczenie lokalnej pamięci podręcznej modułów. Ponownie uruchom bicep restore, aby pobrać moduły z użyciem poprawionych natywnych nazw hostów.

Plik w specyfikacji szablonu

Po utworzeniu specyfikacji szablonu, połącz tę specyfikację szablonu z modułem. Określ specyfikację szablonu w następującym formacie:

module <symbolic-name> 'ts:<sub-id>/<rg-name>/<template-spec-name>:<version>' = {

Aby uprościć plik Bicep, utwórz alias dla grupy zasobów zawierającej specyfikacje szablonu. Gdy używasz aliasu, składnia staje się następująca:

module <symbolic-name> 'ts/<alias>:<template-spec-name>:<version>' = {

Poniższy moduł wdraża specyfikację szablonu w celu utworzenia konta magazynowego. Subskrypcja i grupa zasobów dla specyfikacji szablonu są zdefiniowane w aliasie o nazwie ContosoSpecs.

module stgModule 'ts/ContosoSpecs:storageSpec:2.0' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Korzystanie z dekoratorów

Zapisuj dekoratory w formacie @expression i umieszczaj je powyżej deklaracji modułów. W poniższej tabeli przedstawiono dostępne dekoratory dla modułów:

Decorator Argument Description
batchSize none Konfigurowanie wystąpień w celu sekwencyjnego wdrażania.
description ciąg Podaj opisy modułu.

Dekoratory znajdują się w przestrzeni nazw systemu. Jeśli musisz odróżnić dekorator od innego elementu o tej samej nazwie, poprzedź dekorator prefiksem sys. Jeśli na przykład plik Bicep zawiera parametr o nazwie description, należy dodać przestrzeń nazw sys podczas korzystania z dekoratora description.

BatchSize

Można zastosować @batchSize() tylko do definicji zasobu lub modułu, która używa for wyrażenia.

Domyślnie aparat wdrażania wdraża moduły równolegle. Po dodaniu dekoratora @batchSize(int) instancje są wdrażane szeregowo.

@batchSize(3)
module storage 'br/public:avm/res/storage/storage-account:0.11.1' = [for storageName in storageAccounts: {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}]

Aby uzyskać więcej informacji, zobacz Wdrażanie w partiach.

Description

Aby dodać wyjaśnienie, dodaj opis do deklaracji modułów. Przykład:

@description('Create storage accounts referencing an AVM.')
module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

Tekst opisu można użyć w formacie Markdown.

Parameters

Parametry podane w definicji modułu są zgodne z parametrami w pliku Bicep.

Poniższy przykład Bicep ma trzy parametry: storagePrefix, storageSKUi location. Parametr storageSKU ma wartość domyślną, więc nie trzeba podawać wartości dla tego parametru podczas wdrażania.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

Aby użyć poprzedniego przykładu jako modułu, podaj wartości dla tych parametrów.

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2025-04-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

Ustawianie zakresu modułu

Podczas deklarowania modułu ustaw zakres modułu, który różni się od zakresu pliku Bicep, który go zawiera. scope Użyj właściwości , aby ustawić zakres modułu. Jeśli nie podasz właściwości scope, moduł zostanie wdrożony w docelowym zakresie obiektu nadrzędnego.

Poniższy plik Bicep tworzy grupę zasobów i konto magazynowe w tej grupie zasobów. Plik jest wdrażany w subskrypcji, ale moduł jest przypisany do nowej grupy zasobów.

// set the target scope for this file
targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

param location string = deployment().location

var resourceGroupName = '${namePrefix}rg'

resource newRG 'Microsoft.Resources/resourceGroups@2025-04-01' = {
  name: resourceGroupName
  location: location
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: newRG
  params: {
    storagePrefix: namePrefix
    location: location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

Następny przykład wdraża konta przechowywania do dwóch różnych grup zasobów. Obie te grupy zasobów muszą już istnieć.

targetScope = 'subscription'

resource firstRG 'Microsoft.Resources/resourceGroups@2025-04-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2025-04-01' existing = {
  name: 'demogroup2'
}

module storage1 '../create-storage-account/main.bicep' = {
  name: 'westusdeploy'
  scope: firstRG
  params: {
    storagePrefix: 'stg1'
    location: 'westus'
  }
}

module storage2 '../create-storage-account/main.bicep' = {
  name: 'eastusdeploy'
  scope: secondRG
  params: {
    storagePrefix: 'stg2'
    location: 'eastus'
  }
}

Ustaw właściwość scope na prawidłowy obiekt zakresu. Jeśli plik Bicep wdraża grupę zasobów, subskrypcję lub grupę zarządzania, ustaw zakres modułu na nazwę symboliczną tego zasobu. Możesz też użyć funkcji zakresu, aby uzyskać prawidłowy zakres.

Te funkcje to:

W poniższym przykładzie użyto managementGroup funkcji w celu ustawienia zakresu.

param managementGroupName string

module mgDeploy 'main.bicep' = {
  name: 'deployToMG'
  scope: managementGroup(managementGroupName)
}

Output

Możesz pobrać wartości z modułu i użyć ich w głównym pliku Bicep. Aby uzyskać wartość wyjściową z modułu, użyj outputs właściwości w obiekcie modułu.

Pierwszy przykład tworzy konto magazynowe i zwraca główne punkty końcowe.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

Jeśli używasz właściwości jako modułu, możesz uzyskać następującą wartość wyjściową:

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2025-04-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

Korzystając z programu Bicep w wersji 0.35.1 lub nowszej, można zastosować dekorator @secure() do danych wyjściowych modułu, aby oznaczyć je jako poufne i zapewnić, że ich wartości nie będą ujawniane w dziennikach ani historii wdrożeń. Takie podejście jest przydatne, gdy moduł musi zwrócić poufne dane, takie jak wygenerowany klucz lub parametry połączenia, do nadrzędnego pliku Bicep bez ryzyka ich ujawnienia. Aby uzyskać więcej informacji, zobacz Bezpieczne dane wyjściowe.

Tożsamość modułu

Począwszy od wersji Bicep w wersji 0.36.1, możesz przypisać tożsamość zarządzaną przypisaną przez użytkownika do modułu. Ta tożsamość jest dostępna w module — na przykład w celu uzyskania dostępu do Key Vault. Jednak usługi zaplecza nie obsługują jeszcze tej możliwości.

param identityId string

module mod './module.bicep' = {
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${identityId}': {}
    }
  }
  name: 'mod'
  params: {
    keyVaultUri: 'keyVaultUri'
    identityId: identityId
  }
}
  • Aby przekazać wartość wrażliwą do modułu getSecret , użyj funkcji .