Moduły Bicep

Bicep umożliwia organizowanie wdrożeń w modułach. Moduł to plik Bicep (lub szablon JSON usługi ARM) wdrożony z innego pliku Bicep. 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, rejestr publiczny lub rejestr prywatny. Specyfikacje szablonów i moduły w rejestrze są dostępne tylko dla użytkowników z odpowiednimi uprawnieniami.

Napiwek

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 jeszcze nie używasz Bicep, użyj specyfikacji szablonu.
  • Zawartość rejestru modułów Bicep można wdrożyć tylko z innego pliku Bicep. Specyfikacje szablonów 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 polecenia , aby dostosować środowisko wdrażania portalu.
  • Bicep ma pewne ograniczone możliwości osadzania innych artefaktów projektu (w tym plików szablonów innych niż Bicep i innych niż ARM. Na przykład skrypty programu PowerShell, skrypty interfejsu wiersza polecenia i inne pliki binarne) przy użyciu loadTextContent funkcji i loadFileAsBase64 . Specyfikacje szablonu nie mogą spakować tych artefaktów.

Moduły Bicep są konwertowane na pojedynczy szablon usługi Azure Resource Manager z zagnieżdżonym szablonem. Aby uzyskać więcej informacji na temat sposobu rozpoznawania plików konfiguracji i sposobu scalania pliku konfiguracji zdefiniowanego przez użytkownika Bicep z domyślnym plikiem konfiguracji, zobacz Proces rozpoznawania plików konfiguracji i Proces scalania plików konfiguracji.

Zasoby szkoleniowe

Jeśli wolisz dowiedzieć się więcej o modułach za pomocą szczegółowych wskazówek, zobacz Tworzenie plików Bicep z możliwością komponowania przy użyciu modułów.

Składnia definicji

Podstawowa składnia definiowania modułu to:

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

W związku z tym 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 JSON usługi ARM 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 być plikiem lokalnym lub plikiem w rejestrze. Plik lokalny może być plikiem Bicep lub szablonem JSON usługi ARM. Aby uzyskać więcej informacji, zobacz Ścieżka do modułu.

Właściwość name jest wymagana. Staje się nazwą zagnieżdżonego zasobu wdrożenia w wygenerowanym szablonie.

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 docelowej 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ę.

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')
}

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. Użycie jest 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. Można użyć 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ść, możesz dodać dependsOn do definicji modułu. Aby dowiedzieć się więcej na temat zależności, zobacz Zależności zasobów.

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 rejestrze modułów Bicep. Poniżej przedstawiono wszystkie te opcje.

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 separatora katalogu ukośnika (/), aby zapewnić spójną kompilację na różnych platformach. Znak ukośnika odwrotnego systemu Windows (\) jest nieobsługiwany. Ścieżki mogą zawierać spacje.

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

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

Plik w rejestrze

Rejestr modułów publicznych

Rejestr publicznych modułów jest hostowany w rejestrze kontenerów firmy Microsoft (MCR). Kod źródłowy i moduły są przechowywane w usłudze GitHub. Aby wyświetlić dostępne moduły i ich wersje, zobacz Indeks modułu rejestru Bicep.

The screenshot of public module registry.

Wybierz wersje, aby wyświetlić dostępne wersje. Możesz również wybrać pozycję Kod źródłowy, aby wyświetlić kod źródłowy modułu, a następnie otworzyć pliki Readme.

Obecnie istnieje tylko kilka opublikowanych modułów. Nadchodzi więcej modułów. Jeśli chcesz współtworzyć rejestr, zapoznaj się z przewodnikiem dotyczącym współtworzenia.

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

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public to alias rejestru modułów publicznych. Ten alias jest wstępnie zdefiniowany w konfiguracji.
  • Ścieżka pliku może zawierać segmenty, które mogą być oddzielone znakiem / .
  • tag służy do określania wersji modułu.

Na przykład:

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

Uwaga

br/public jest aliasem dla rejestru publicznego. Można go również napisać jako

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 to nazwa schematu rejestru Bicep.
  • Ścieżka pliku jest wywoływana 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.

Na przykład:

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

Podczas odwołowania się do modułu w rejestrze rozszerzenie Bicep w programie Visual Studio Code automatycznie wywołuje funkcję przywracania bicep w celu skopiowania modułu zewnętrznego 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, można skonfigurować 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'
  }
}

Alias dla publicznego rejestru modułów został wstępnie zdefiniowany:

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

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

Plik w specyfikacji szablonu

Po utworzeniu specyfikacji szablonu możesz utworzyć link do tej specyfikacji szablonu w module. Określ specyfikację szablonu w następującym formacie:

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

Można jednak uprościć plik Bicep, tworząc 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 magazynu. 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'
  }
}

Parametry

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

Poniższy przykład Bicep zawiera trzy parametry : storagePrefix, storageSKU i 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@2021-04-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@2021-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 można ustawić zakres modułu, który różni się od zakresu zawierającego plik Bicep. scope Użyj właściwości , aby ustawić zakres modułu. Gdy właściwość zakresu nie zostanie podana, moduł zostanie wdrożony w zakresie docelowym elementu nadrzędnego.

Poniższy plik Bicep tworzy grupę zasobów i konto magazynu w tej grupie zasobów. Plik jest wdrażany w subskrypcji, ale moduł jest w zakresie 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@2021-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

W następnym przykładzie są wdrażane konta magazynu w dwóch różnych grupach zasobów. Obie te grupy zasobów muszą już istnieć.

targetScope = 'subscription'

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

resource secondRG 'Microsoft.Resources/resourceGroups@2021-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ść zakresu 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)
}

Wyjście

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 magazynu i zwraca podstawowe 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@2021-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

W przypadku użycia jako modułu możesz uzyskać wartość wyjściową.

targetScope = 'subscription'

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

resource demoRG 'Microsoft.Resources/resourceGroups@2021-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

Następne kroki