Модули Bicep

Bicep позволяет упорядочивать развертывания по модулям. Модуль — это файл Bicep (или JSON-шаблон ARM), развернутый из другого файла Bicep. Модули позволяют повысить удобочитаемость файлов Bicep за счет инкапсуляции сложных сведений о развертывании. Кроме того, модули можно многократно использовать для разных развертываний.

Для совместного использования модулей с другими сотрудниками организации создайте спецификацию шаблона, общедоступный реестр или частный реестр. Спецификации шаблонов и модули в реестре доступны только пользователям с правильными разрешениями.

Совет

Выбор между реестром модулей и спецификациями шаблонов определяется в основном личными предпочтениями. Но при выборе между этими двумя вариантами следует учитывать ряд моментов.

  • Реестр модулей поддерживается только для Bicep. Если вы пока не используете Bicep, выбирайте спецификации шаблонов.
  • Содержимое в реестре модулей Bicep можно развернуть только из другого файла Bicep. Спецификации шаблонов можно развертывать непосредственно из API, Azure PowerShell, Azure CLI или на портале Azure. Вы даже можете использовать UiFormDefinition для настройки интерфейса развертывания на портале.
  • Bicep предоставляет ограниченную поддержку для внедрения других артефактов проекта, включая файлы, отличные от Bicep, и файлы, отличные от файлов шаблонов ARM (например, скрипты PowerShell, скрипты CLI и другие двоичные файлы), с помощью функций loadTextContent и loadFileAsBase64. Спецификации шаблонов не умеют упаковывать такие артефакты.

Модули Bicep преобразуются в один шаблон Resource Manager со вложенными шаблонами. Дополнительные сведения о том, как Bicep разрешает файлы конфигурации и как файл конфигурации, определяемый пользователем Bicep, с файлом конфигурации по умолчанию, см. в разделе "Процесс разрешения файлов конфигурации" и процесс слияния файлов конфигурации.

Обучающие материалы

Если вам нужны пошаговые инструкции для изучения модулей, см. статью Создание составляющих файлов Bicep с помощью модулей.

Синтаксис определения

Базовая структура синтаксиса для определения модуля:

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

Итак, простой реальный пример выглядит следующим образом:

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

В качестве модуля также можно использовать JSON-шаблон ARM:

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

Используйте символьное имя для ссылки на модуль в другой части файла Bicep. Например, символьное имя можно использовать для получения результатов из модуля. Символьное имя может содержать a-z, A-Z, 0-9 и подчеркивание (_). Имя не должно начинаться с цифры. Имя модуля не может совпадать с именем параметра, переменной или ресурса.

В качестве пути можно использовать локальный файл или файл в реестре. Локальный файл может быть Bicep-файлом или JSON-шаблоном ARM. Дополнительные сведения см. в статье Путь к модулю.

Свойство Имя является обязательным. Оно становится именем ресурса вложенного развертывания в шаблоне.

Если модуль со статическим именем развертывается одновременно в одной области, есть вероятность того, что одно развертывание будет мешать выходным данным другого развертывания. Например, если два файла Bicep используют один модуль с одинаковым статическим именем (examplemodule) и нацелены на одну и ту же группу ресурсов, одно развертывание может показать неправильные выходные данные. Если вас беспокоит ситуация с одновременными развертываниями в одной области, присвойте модулю уникальное имя.

В следующем примере имя развертывания объединяется с именем модуля. Если вы укажете уникальное имя для развертывания, имя модуля также будет уникальным.

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

Если вам нужно указать область, отличную от области основного файла, добавьте свойство "Область действия". Дополнительные сведения см. в разделе Задание области модуля.

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

Чтобы условно развернуть модуль, добавьте выражение if. Использование аналогично условному развертыванию ресурса.

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

Чтобы развернуть более одного экземпляра модуля, добавьте выражение for. Можно указать, следует ли развертывать экземпляры последовательно или параллельно, с помощью декоратора batchSize. Дополнительные сведения о циклах см. в статье Интерактивные циклы в 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>
  }
}]

Как и ресурсы, модули развертываются параллельно, если только они не зависят от других модулей или ресурсов. Как правило, задавать зависимости не нужно, так как они определяются неявным образом. Если нужно задать явную зависимость, можно добавить dependsOn в определение модуля. Дополнительные сведения о зависимостях см. в статье Зависимости ресурсов.

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

Путь к модулю

Файл для модуля может быть локальным или внешним. Внешний файл может содержаться в спецификации шаблона или в реестре модуля Bicep. Все эти варианты представлены ниже.

Локальный файл

Если модуль представляет собой локальный файл, укажите относительный путь к этому файлу. Все пути в Bicep должны быть указаны с помощью разделителя каталогов косой черты (/), чтобы обеспечить согласованную компиляцию на разных платформах. Символ обратной косой черты Windows (\) не поддерживается. Пути могут содержать пробелы.

Например, чтобы развернуть файл в каталоге на уровень выше основного файла, используйте:

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

Файл в реестре

Общедоступный реестр модулей

Общедоступный реестр модулей размещается в реестре контейнеров Майкрософт (MCR). Исходный код и модули хранятся в GitHub. Чтобы просмотреть доступные модули и их версии, ознакомьтесь с индексом модуля реестра Bicep.

The screenshot of public module registry.

Выберите версии, чтобы проверить их доступность. Вы также можете выбрать исходный код модуля, чтобы просмотреть исходный код модуля и открыть файлы Readme.

В настоящее время существует не более двух-трех опубликованных модулей. Будут доступны дополнительные модули. Если вы хотите внести свой вклад в реестр, ознакомьтесь с руководством по участию.

Чтобы создать ссылку на модуль общедоступного реестра, укажите путь к модулю, используя следующий синтаксис:

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public — это псевдоним для общедоступного реестра модулей. Этот псевдоним предопределен в конфигурации.
  • путь к файлу может содержать сегменты, разделенные символом /.
  • Тег используется для указания версии модуля.

Рассмотрим пример.

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

Примечание.

br/public — это псевдоним для общедоступного реестра. Его также можно записать в виде

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

Частный реестр модулей

Если вы опубликовали модуль в реестре, можно создать ссылку на этот модуль. Укажите имя реестра контейнеров Azure и путь к модулю. Укажите путь к модулю с помощью следующей структуры синтаксиса.

module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
  • br — имя схемы для реестра Bicep.
  • Путь к файлу в реестре контейнеров Azure называется repository. Путь к файлу может содержать сегменты, разделенных символом /.
  • Тег используется для указания версии модуля.

Например:

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

При ссылке на модуль в реестре расширение Bicep в Visual Studio Code автоматически вызывает восстановление Bicep для копирования внешнего модуля в локальный кэш. Восстановление внешнего модуля занимает несколько секунд. Если технология IntelliSense для модуля срабатывает не сразу, дождитесь завершения восстановления.

Полный путь к модулю в реестре может быть длинным. Вместо того чтобы указывать полный путь каждый раз при использовании модуля, можно настроить псевдонимы в файле bicepconfig.json. Псевдонимы упрощают обращение к модулю. Например, с помощью псевдонима можно сократить путь до следующего вида:

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

Псевдоним для общедоступного реестра модулей задан заранее:

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

Вы можете переопределить общедоступный псевдоним в файле bicepconfig.json.

Файл в спецификации шаблона

После создания спецификации шаблона можно создать ссылку на спецификацию шаблона в модуле. Укажите спецификацию шаблона в следующем формате:

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

Однако можно упростить файл Bicep, создав псевдоним для группы ресурсов, которая содержит спецификации шаблонов. При использовании псевдонима синтаксис будет выглядеть так:

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

Следующий модуль развертывает спецификацию шаблона для создания учетной записи хранения. Подписка и группа ресурсов для спецификации шаблона определяются в псевдониме ContosoSpecs.

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

Параметры

Параметры, указанные в определении модуля, соответствуют параметрам в файле Bicep.

В следующем примере Bicep имеется три параметра: storagePrefix, storageSKU и location. Параметр storageSKU имеет значение по умолчанию, поэтому в ходе развертывания вам не нужно будет указывать значение этого параметра.

@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

Чтобы использовать предыдущий пример в качестве модуля, укажите значения для этих параметров.

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

Задание области действия модуля

При объявлении модуля можно задать область действия модуля, отличную от области действия файла Bicep, в котором он содержится. Используйте свойство scope, чтобы настроить область действия для модуля. Если свойство scope не указано, модуль развертывается в родительской целевой области.

Следующий файл Bicep создает группу ресурсов и учетную запись хранения в этой группе ресурсов. Файл развертывается в подписке, однако область действия модуля ограничивается новой группой ресурсов.

// 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

В следующем примере учетные записи хранения развертываются в двух разных группах ресурсов. Обе эти группы ресурсов уже должны существовать.

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

Задайте для свойства scope допустимый объект области. Если файл Bicep развертывает группу ресурсов, подписку или группу управления, можно задать в качестве области модуля символьное имя этого ресурса. Для получения допустимой области можно также использовать функции области.

Такими функциями являются:

В следующем примере для задания области используется функция managementGroup.

param managementGroupName string

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

Выходные данные

Можно получить значения от модуля и использовать их в основном файле Bicep. Чтобы получить выходное значение от модуля, используйте свойство outputs в объекте модуля.

В первом примере создается учетная запись хранения и возвращаются основные конечные точки.

@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

При использовании в качестве модуля можно получить это выходное значение.

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

Следующие шаги