Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье приводятся сведения об использовании синтаксиса for
для итерации по элементам в коллекции. Эта функция поддерживается, начиная с версии 0.3.1. С помощью циклов можно определить несколько копий ресурса, модуля, переменной, свойства или выходных данных. Циклы позволяют избежать повторения синтаксиса в файле Bicep и динамически настроить количество копий, создаваемых во время развертывания.
См. краткое руководство «Создание нескольких экземпляров ресурсов в Bicep», чтобы узнать, как использовать различные синтаксисы для создания нескольких экземпляров ресурсов в Bicep.
Чтобы использовать циклы для создания нескольких ресурсов или модулей, каждый экземпляр должен иметь уникальное значение для name
свойства. Для создания имен можно использовать значение индекса или уникальные значения в массивах или коллекциях.
Обучающие материалы
См. пошаговое руководство по использованию условий и циклов в разделе Создание гибких файлов Bicep с использованием условий и циклов на Microsoft Learn.
Синтаксис циклов
Ниже приводятся способы объявления циклов.
Использование целочисленного индекса. Этот вариант работает в случае, если нужно создать определенное количество экземпляров. Функция range создает массив целых чисел, который начинается с начального индекса и содержит указанное количество элементов. В цикле целочисленный индекс можно использовать для изменения значений. Дополнительные сведения см. в разделе Целочисленный индекс.
[for <index> in range(<startIndex>, <numberOfElements>): { ... }]
Использование элементов в массиве: этот параметр работает, когда сценарий имеет значение "Я хочу создать экземпляр для каждого элемента в массиве". В цикле можно использовать значение текущего элемента массива для изменения значений. Дополнительные сведения см. в разделе Элементы массива.
[for <item> in <collection>: { ... }]
Использование элементов в объекте словаря: этот параметр работает, когда сценарий имеет значение "Я хочу создать экземпляр для каждого элемента в объекте". Функция items преобразует объект в массив. В цикле свойства объекта можно использовать для создания значений. Дополнительные сведения см. в разделе Объект Dictionary.
[for <item> in items(<object>): { ... }]
Использование целочисленного индекса и элементов в массиве: этот параметр работает, когда сценарий имеет значение: "Я хочу создать экземпляр для каждого элемента в массиве, но мне также нужен текущий индекс для создания другого значения". Дополнительные сведения см. в разделе "Массив циклов" и "индекс".
[for (<item>, <index>) in <collection>: { ... }]
Добавление условного развертывания: этот параметр работает, если сценарий имеет значение "Я хочу создать несколько экземпляров, но я хочу развернуть каждый экземпляр только в том случае, если условие имеет значение true". Дополнительные сведения см. в разделе "Цикл с условием".
[for <item> in <collection>: if(<condition>) { ... }]
Ограничения цикла
При использовании циклов в Bicep действуют следующие ограничения:
- Циклы Bicep работают только с теми значениями, которые можно установить в начале развертывания.
- Количество итераций в цикле не может быть отрицательным или превышать 800 итераций.
- Так как ресурс не может циклировать с вложенными дочерними ресурсами, измените дочерние ресурсы на ресурсы верхнего уровня. Дополнительные сведения см. в разделе "Итерация" для дочернего ресурса.
- Чтобы выполнить цикл на нескольких уровнях свойств, используйте лямбда-функцию
map
.
Целочисленный индекс
Для простого примера использования индекса создайте переменную , содержащую массив строк:
param itemCount int = 5
var stringArray = [for i in range(0, itemCount): 'item${(i + 1)}']
output arrayResult array = stringArray
Получаемыми выходными данными является массив со следующими значениями:
[
"item1",
"item2",
"item3",
"item4",
"item5"
]
В следующем примере создается заданное в параметре storageCount
число учетных записей хранения. Он возвращает три свойства для каждой учетной записи хранения:
param location string = resourceGroup().location
param storageCount int = 2
resource storageAcct 'Microsoft.Storage/storageAccounts@2023-05-01' = [for i in range(0, storageCount): {
name: '${i}storage${uniqueString(resourceGroup().id)}'
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'Storage'
}]
output storageInfo array = [for i in range(0, storageCount): {
id: storageAcct[i].id
blobEndpoint: storageAcct[i].properties.primaryEndpoints.blob
status: storageAcct[i].properties.statusOfPrimary
}]
Обратите внимание на то, что при создании имени ресурса учетной записи хранения используется индекс i
.
Следующий пример развертывает модуль несколько раз:
param location string = resourceGroup().location
param storageCount int = 2
var baseName = 'store${uniqueString(resourceGroup().id)}'
module stgModule './storageAccount.bicep' = [for i in range(0, storageCount): {
name: '${i}deploy${baseName}'
params: {
storageName: '${i}${baseName}'
location: location
}
}]
output storageAccountEndpoints array = [for i in range(0, storageCount): {
endpoint: stgModule[i].outputs.storageEndpoint
}]
Элементы массива
В следующем примере создается одна учетная запись хранения для каждого имени, указанного в параметре storageNames
. Обратите внимание, что свойство name для каждого экземпляра ресурса должно быть уникальным:
param location string = resourceGroup().location
param storageNames array = [
'contoso'
'fabrikam'
'coho'
]
resource storageAcct 'Microsoft.Storage/storageAccounts@2023-05-01' = [for name in storageNames: {
name: '${name}${uniqueString(resourceGroup().id)}'
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'Storage'
}]
Следующий пример выполняет итерацию по массиву для определения свойства. Он создает две подсети в виртуальной сети. Обратите внимание, что имена подсети должны быть уникальными:
param rgLocation string = resourceGroup().location
var subnets = [
{
name: 'api'
subnetPrefix: '10.144.0.0/24'
}
{
name: 'worker'
subnetPrefix: '10.144.1.0/24'
}
]
resource vnet 'Microsoft.Network/virtualNetworks@2023-11-01' = {
name: 'vnet'
location: rgLocation
properties: {
addressSpace: {
addressPrefixes: [
'10.144.0.0/20'
]
}
subnets: [for subnet in subnets: {
name: subnet.name
properties: {
addressPrefix: subnet.subnetPrefix
}
}]
}
}
Массив и индекс
В следующем примере при определении учетной записи хранения используется как элемент массива, так и значение индекса:
param storageAccountNamePrefix string
var storageConfigurations = [
{
suffix: 'local'
sku: 'Standard_LRS'
}
{
suffix: 'geo'
sku: 'Standard_GRS'
}
]
resource storageAccountResources 'Microsoft.Storage/storageAccounts@2023-05-01' = [for (config, i) in storageConfigurations: {
name: '${storageAccountNamePrefix}${config.suffix}${i}'
location: resourceGroup().location
sku: {
name: config.sku
}
kind: 'StorageV2'
}]
В следующем примере используются как элементы массива, так и индекс для вывода сведений о новых ресурсах:
param location string = resourceGroup().location
param orgNames array = [
'Contoso'
'Fabrikam'
'Coho'
]
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-11-01' = [for name in orgNames: {
name: 'nsg-${name}'
location: location
}]
output deployedNSGs array = [for (name, i) in orgNames: {
orgName: name
nsgName: nsg[i].name
resourceId: nsg[i].id
}]
Объект Dictionary
Чтобы выполнить итерацию элементов в объекте словаря, используйте items
функцию, которая преобразует объект в массив. Получить свойства объектов можно с помощью свойства value
. Обратите внимание, что имена ресурсов nsg должны быть уникальными.
param nsgValues object = {
nsg1: {
name: 'nsg-westus1'
location: 'westus'
}
nsg2: {
name: 'nsg-east1'
location: 'eastus'
}
}
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-11-01' = [for nsg in items(nsgValues): {
name: nsg.value.name
location: nsg.value.location
}]
Цикл с условием
Для ресурсов и модулей можно добавить выражение if
с синтаксисом цикла для условного развертывания коллекции.
В следующем примере показан цикл в сочетании с условным оператором. В этом примере к всем экземплярам модуля применяется одно условие:
param location string = resourceGroup().location
param storageCount int = 2
param createNewStorage bool = true
var baseName = 'store${uniqueString(resourceGroup().id)}'
module stgModule './storageAccount.bicep' = [for i in range(0, storageCount): if(createNewStorage) {
name: '${i}deploy${baseName}'
params: {
storageName: '${i}${baseName}'
location: location
}
}]
В следующем примере показано, как применить условие, относящееся к текущему элементу в массиве:
resource parentResources 'Microsoft.Example/examples@2024-06-06' = [for parent in parents: if(parent.enabled) {
name: parent.name
properties: {
children: [for child in parent.children: {
name: child.name
setting: child.settingValue
}]
}
}]
Развертывание в пакетах
Ресурсы Azure развертываются параллельно по умолчанию. При использовании цикла для создания нескольких экземпляров типа ресурса, развертывание всех этих экземпляров происходит одновременно. Порядок, в котором они создаются, не гарантируется. Количество ресурсов, развернутых параллельно, ограничивается только общим лимитом в 800 ресурсов в файле Bicep.
Вам может не потребоваться одновременное обновление всех экземпляров типа ресурса. Например, при обновлении производственной среды, возможно, потребуется распределить обновления так, чтобы в любой момент времени обновлялось только определенное количество. Можно указать подмножество экземпляров, которые будут пакетированы вместе и развертываться одновременно. Остальные экземпляры ожидают пока этот пакет будет готов.
Чтобы последовательно развернуть экземпляры ресурса, добавьте декоратор batchSize
. Задайте его значение, равное количеству экземпляров для одновременного развертывания. Зависимость создается во время предыдущих экземпляров цикла, поэтому она не запускает один пакет до завершения предыдущего пакета.
param location string = resourceGroup().location
@batchSize(2)
resource storageAcct 'Microsoft.Storage/storageAccounts@2023-05-01' = [for i in range(0, 4): {
name: '${i}storage${uniqueString(resourceGroup().id)}'
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'Storage'
}]
Для последовательного развертывания задайте в качестве размера пакета значение 1.
Декоратор batchSize
находится в пространстве имен sys. Если вам важно не путать этот декоратор с другими элементами с таким же именем, добавьте к нему префикс sys: @sys.batchSize(2)
.
Итерация для дочернего ресурса
Чтобы создать несколько экземпляров дочернего ресурса, обе из следующих файлов Bicep поддерживают эту задачу:
Вложенные дочерние ресурсы
param location string = resourceGroup().location
resource stg 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: 'examplestorage'
location: location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
resource service 'fileServices' = {
name: 'default'
resource share 'shares' = [for i in range(0, 3): {
name: 'exampleshare${i}'
}]
}
}
Дочерние ресурсы высокого уровня
resource stg 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: 'examplestorage'
location: resourceGroup().location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
}
resource service 'Microsoft.Storage/storageAccounts/fileServices@2023-05-01' = {
name: 'default'
parent: stg
}
resource share 'Microsoft.Storage/storageAccounts/fileServices/shares@2023-05-01' = [for i in range(0, 3): {
name: 'exampleshare${i}'
parent: service
}]
Справочные коллекции ресурсов и модулей
Функция шаблона Azure Resource Manager (шаблон ARM) references
возвращает массив объектов, представляющих состояния среды выполнения коллекции ресурсов. Так как в Bicep нет явной references
функции, и символьные коллекции используются напрямую, Bicep преобразует это в шаблон ARM, который использует функцию шаблона references
ARM в процессе генерации кода. Для функции перевода, которая использует references
функцию для преобразования символьных коллекций в шаблоны ARM, необходимо иметь Bicep CLI версии 0.20.X или более поздней. Кроме того, в файлеbicepconfig.json параметр symbolicNameCodegen
должен быть представлен и установлен на true
.
Выходные данные двух примеров в целочисленном индексе можно записать следующим образом:
param location string = resourceGroup().location
param storageCount int = 2
resource storageAcct 'Microsoft.Storage/storageAccounts@2023-05-01' = [for i in range(0, storageCount): {
name: '${i}storage${uniqueString(resourceGroup().id)}'
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'Storage'
}]
output storageInfo array = map(storageAcct, store => {
blobEndpoint: store.properties.primaryEndpoints
status: store.properties.statusOfPrimary
})
output storageAccountEndpoints array = map(storageAcct, store => store.properties.primaryEndpoints)
Этот файл Bicep преобразуется в следующий шаблон JSON ARM, использующий функцию references
:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "1.10-experimental",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"storageCount": {
"type": "int",
"defaultValue": 2
}
},
"resources": {
"storageAcct": {
"copy": {
"name": "storageAcct",
"count": "[length(range(0, parameters('storageCount')))]"
},
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-04-01",
"name": "[format('{0}storage{1}', range(0, parameters('storageCount'))[copyIndex()], uniqueString(resourceGroup().id))]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage"
}
},
"outputs": {
"storageInfo": {
"type": "array",
"value": "[map(references('storageAcct', 'full'), lambda('store', createObject('blobEndpoint', lambdaVariables('store').properties.primaryEndpoints, 'status', lambdaVariables('store').properties.statusOfPrimary)))]"
},
"storageAccountEndpoints": {
"type": "array",
"value": "[map(references('storageAcct', 'full'), lambda('store', lambdaVariables('store').properties.primaryEndpoints))]"
}
}
}
Обратите внимание, что в предыдущем шаблоне JSON ARM languageVersion
должен быть установлен как 1.10-experimental
, и элемент ресурса является объектом, а не массивом.
Следующие шаги
Сведения о создании файлов Bicep см. в статье "Структура и синтаксис Bicep".