Iterativní smyčky v Bicep
V tomto článku se dozvíte, jak pomocí for
syntaxe iterovat položky v kolekci. Tato funkce se podporuje od verze 0.3.1 dále. Pomocí smyček můžete definovat více kopií prostředku, modulu, proměnné, vlastnosti nebo výstupu. Pomocí smyček se vyhnete opakování syntaxe v souboru Bicep a dynamicky nastavíte počet kopií, které se mají během nasazení vytvořit. Pokud chcete projít rychlý start, přečtěte si článek Rychlý start: Vytvoření více instancí.
Pokud chcete k vytvoření více prostředků nebo modulů použít smyčky, musí mít každá instance jedinečnou hodnotu vlastnosti name. Názvy můžete vytvořit pomocí hodnoty indexu nebo jedinečných hodnot v polích nebo kolekcích.
Školicí materiály
Pokud byste se raději dozvěděli o smyčkách podrobných pokynů, přečtěte si téma Vytváření flexibilních šablon Bicep pomocí podmínek a smyček.
Syntaxe smyčky
Smyčky lze deklarovat pomocí:
Použití celočíselného indexu Tato možnost funguje, pokud je váš scénář: "Chci vytvořit tento počet instancí". Funkce rozsahu vytvoří pole celých čísel, které začínají na počátečním indexu a obsahují počet zadaných prvků. Ve smyčce můžete k úpravě hodnot použít celočíselné indexy. Další informace naleznete v tématu Integer index.
[for <index> in range(<startIndex>, <numberOfElements>): { ... }]
Použití položek v poli Tato možnost funguje, pokud je váš scénář: "Chci vytvořit instanci pro každý prvek v poli". Ve smyčce můžete k úpravě hodnot použít hodnotu aktuálního prvku pole. Další informace naleznete v tématu Prvky pole.
[for <item> in <collection>: { ... }]
Použití položek v objektu slovníku Tato možnost funguje, pokud je váš scénář: "Chci vytvořit instanci pro každou položku v objektu". Funkce items převede objekt na pole. Ve smyčce můžete k vytvoření hodnot použít vlastnosti z objektu. Další informace naleznete v tématu Dictionary objekt.
[for <item> in items(<object>): { ... }]
Použití celočíselného indexu a položek v poli Tato možnost funguje, když je váš scénář: "Chci vytvořit instanci pro každý prvek v poli, ale k vytvoření další hodnoty potřebuji také aktuální index." Další informace naleznete v tématu Smyčka pole a index.
[for (<item>, <index>) in <collection>: { ... }]
Přidání podmíněného nasazení Tato možnost funguje, pokud je váš scénář: "Chci vytvořit více instancí, ale pro každou instanci, kterou chci nasadit pouze v případě, že je splněna podmínka". Další informace naleznete v tématu Smyčka s podmínkou.
[for <item> in <collection>: if(<condition>) { ... }]
Omezení smyčky
Používání smyček v Bicep má tato omezení:
- Smyčky Bicep pracují pouze s hodnotami, které je možné určit na začátku nasazení.
- Iterace smyčky nesmí být záporné číslo nebo nesmí překročit 800 iterací.
- Prostředek nelze opakovat s vnořenými podřízenými prostředky. Změňte podřízené prostředky na prostředky nejvyšší úrovně. Viz iterace pro podřízený prostředek.
- Pokud chcete provést smyčku na více úrovních vlastností, použijte funkci mapování lambda.
Celočíselná index
Pro jednoduchý příklad použití indexu vytvořte proměnnou, která obsahuje pole řetězců.
param itemCount int = 5
var stringArray = [for i in range(0, itemCount): 'item${(i + 1)}']
output arrayResult array = stringArray
Výstup vrátí matici s následujícími hodnotami:
[
"item1",
"item2",
"item3",
"item4",
"item5"
]
Další příklad vytvoří počet účtů úložiště zadaných v parametru storageCount
. Vrátí tři vlastnosti pro každý účet úložiště.
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
}]
Všimněte si, že se index i
používá při vytváření názvu prostředku účtu úložiště.
Další příklad několikrát nasadí modul.
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
}]
Prvky pole
Následující příklad vytvoří jeden účet úložiště pro každý název zadaný v parametru storageNames
. Poznamenejte si vlastnost názvu pro každou instanci prostředku musí být jedinečná.
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'
}]
Další příklad iteruje přes pole k definování vlastnosti. Vytvoří dvě podsítě ve virtuální síti. Všimněte si, že názvy podsítí musí být jedinečné.
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
}
}]
}
}
Pole a index
V následujícím příkladu se při definování účtu úložiště používá element pole i hodnota indexu.
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'
}]
V dalším příkladu se k výstupu informací o nových prostředcích používají prvky pole i index.
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
}]
Objekt slovníku
Chcete-li iterovat prvky v objektu slovníku, použijte funkci items, která převede objekt na pole. value
Vlastnost slouží k získání vlastností objektů. Všimněte si, že názvy prostředků NSG musí být jedinečné.
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
}]
Smyčka s podmínkou
Pro prostředky a moduly můžete přidat if
výraz se syntaxí smyčky pro podmíněné nasazení kolekce.
Následující příklad ukazuje smyčku v kombinaci s příkazem podmínky. V tomto příkladu se pro všechny instance modulu použije jedna podmínka.
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
}
}]
Další příklad ukazuje, jak použít podmínku specifickou pro aktuální prvek v poli.
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
}]
}
}]
Nasazení v dávkách
Ve výchozím nastavení se prostředky Azure nasazují paralelně. Když k vytvoření více instancí typu prostředku použijete smyčku, všechny tyto instance se nasadí současně. Pořadí, ve kterém jsou vytvořené, není zaručeno. Počet prostředků nasazených paralelně není omezen, kromě celkového limitu 800 prostředků v souboru Bicep.
Možná nebudete chtít aktualizovat všechny instance typu prostředku najednou. Například při aktualizaci produkčního prostředí můžete chtít aktualizace rozmístit tak, aby se aktualizovalo jenom určité číslo najednou. Můžete určit, že podmnožina instancí se dávková společně a současně nasadí. Ostatní instance čekají na dokončení této dávky.
Chcete-li serialně nasadit instance prostředku, přidejte dekorátor batchSize. Nastavte jeho hodnotu na počet instancí, které se mají nasadit souběžně. Závislost se vytvoří na dřívějších instancích ve smyčce, takže nespustí jednu dávku, dokud se předchozí dávka nedokončí.
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'
}]
Pro sekvenční nasazení nastavte velikost dávky na 1.
Dekorátor batchSize
je v oboru názvů sys. Pokud potřebujete odlišit tento dekorátor od jiné položky se stejným názvem, předkožte dekorátor sys:@sys.batchSize(2)
Iterace pro podřízený prostředek
Pokud chcete vytvořit více než jednu instanci podřízeného prostředku, budou fungovat oba následující soubory Bicep.
Vnořené podřízené prostředky
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}'
}]
}
}
Podřízené prostředky nejvyšší úrovně
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
}]
Referenční kolekce prostředků nebo modulů
Funkce šablony references
ARM vrátí pole objektů představujících stavy modulu runtime kolekce prostředků. V Bicep neexistuje žádná explicitní odkazová funkce. Místo toho se používá symbolické použití kolekce přímo a během generování kódu ji Bicep přeloží na šablonu ARM, která využívá funkci odkazy na šablonu ARM. Pro funkci překladu, která transformuje symbolické kolekce na šablony ARM pomocí funkce reference, je nutné mít Rozhraní příkazového řádku Bicep verze 0.20.X nebo vyšší. Kromě toho bicepconfig.json
v souboru symbolicNameCodegen
by mělo být nastavení prezentováno a nastaveno na true
.
Výstupy dvou ukázek v celočíselném indexu lze zapsat takto:
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)
Tento soubor Bicep se přeloží do následující šablony references
JSON ARM, která tuto funkci využívá:
{
"$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))]"
}
}
}
Všimněte si, že v předchozí šabloně languageVersion
JSON ARM musí být nastavena na 1.10-experimental
hodnotu a prvek prostředku je objekt místo pole.