Udostępnij przez


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. Dzięki modułom 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. Istnieje kilka kwestii, które należy wziąć pod uwagę podczas wyboru między nimi:

  • Rejestr modułów jest obsługiwany tylko przez Bicep. Jeśli nie używasz Bicep, użyj specyfikacji szablonu.
  • 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 zasobu wdrożenia zagnieżdżonego.

Jeśli moduł o nazwie statycznej jest wdrażany współbieżnie w tym samym zakresie, istnieje możliwość ingerowania w 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 zapewnienia unikatowych nazw modułów jest pozostawienie name właściwości, a unikatowa nazwa modułu zostanie wygenerowana automatycznie.

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 zostanie wygenerowany jako nazwa modułu.

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

Jeśli musisz określić zakres inny niż zakres 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

Plik modułu może być plikiem lokalnym lub plikiem zewnętrznym. Plik zewnętrzny może znajdować się 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. Wszystkie ścieżki w Bicep muszą być określone przy użyciu ukośnika (/) jako separatora katalogu, aby zapewnić spójną kompilację na różnych platformach. Znak ukośnika odwrotnego Windows (\) nie jest obsługiwany. Ścieżki mogą zawierać spacje.

Aby na przykład wdrożyć plik, który znajduje się na jednym poziomie w katalogu z pliku głównego, użyj polecenia:

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. Zostały one zaprojektowane w celu uproszczenia i przyspieszenia procesu wdrażania dla typowych zasobów i konfiguracji platformy Azure. Moduły są również dostosowane do najlepszych rozwiązań, takich jak Azure Well-Architected Framework.

Przeglądaj moduły Bicep, by 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, które można oddzielić znakiem / .
  • tag: służy do określania wersji 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: służy do określania wersji 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 .

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ą definiowane w aliasie o nazwie ContosoSpecs.

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

Korzystanie z dekoratorów

Dekoratory są zapisywane w postaci @expression i umieszczane nad deklaracjami 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 oznaczeniem 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 moduły są wdrażane 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. Gdy właściwość scope nie zostanie podana, moduł zostanie wdrożony w docelowym zakresie elementu 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, możesz ustawić zakres modułu na nazwę symboliczną dla 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

Gdy właściwość jest używana jako moduł, 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

W wersji 0.35.1 lub nowszej Bicep, dekorator @secure() można zastosować do danych wyjściowych modułu, aby oznaczyć je jako poufne, zapewniając, że ich wartości nie są ujawniane w dziennikach ani historii wdrożenia. Jest to przydatne, gdy moduł musi zwrócić poufne dane, takie jak wygenerowany klucz lub parametry połączenia, do nadrzędnego pliku Bicep bez ryzyka narażenia. 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. Dzięki temu tożsamość jest dostępna w module, na przykład w celu uzyskania dostępu do usługi Key Vault. Jednak ta funkcja jest przeznaczona do użytku w przyszłości i nie jest jeszcze obsługiwana przez usługi zaplecza.

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 .