Iterativní smyčky v nástroji Bicep

V tomto článku se dozvíte, jak pomocí for syntaxe iterovat položky v kolekci. Tato funkce je podporována od verze 0.3.1 a vyšší. Pomocí smyček můžete definovat více kopií prostředku, modulu, proměnné, vlastnosti nebo výstupu. Použijte smyčky, abyste se vyhnuli opakování syntaxe v souboru Bicep a dynamicky nastavili počet kopií, které se mají vytvořit během nasazení. Rychlý start najdete v tématu Rychlý start: Vytvoření více instancí.

Chcete-li použít smyčky k vytvoření více prostředků nebo modulů, musí mít každá instance jedinečnou hodnotu vlastnosti name. K vytvoření názvů můžete použít hodnotu indexu nebo jedinečné hodnoty v polích nebo kolekcích.

Školicí materiály

Pokud byste se raději o smyčkách dozvěděli prostřednictvím 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číná počátečním indexem a obsahuje počet zadaných prvků. V rámci smyčky můžete k úpravě hodnot použít celočíselný index. Další informace najdete v tématu Celočíselný 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. V rámci smyčky můžete k úpravě hodnot použít hodnotu aktuálního prvku pole. Další informace najdete 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. V rámci smyčky můžete k vytvoření hodnot použít vlastnosti z objektu. Další informace najdete v tématu Objekt slovníku.

    [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 potřebuji také aktuální index k vytvoření další hodnoty." Další informace najdete v tématu Pole smyčky 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 chci nasadit pouze v případě, že je splněna podmínka." Další informace najdete v tématu Smyčka s podmínkou.

    [for <item> in <collection>: if(<condition>) {
      ...
    }]
    

Limity smyčky

Použití smyček v Bicep má tato omezení:

  • Smyčky Bicep fungují pouze s hodnotami, které je možné určit na začátku nasazení.
  • Iterace smyčky nesmí být záporné číslo ani 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 podřízeného prostředku.
  • Ke smyčce na více úrovních vlastností použijte funkci lambda map.

Celočíselný index

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í pole 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 . Pro každý účet úložiště vrátí tři vlastnosti.

param location string = resourceGroup().location
param storageCount int = 2

resource storageAcct 'Microsoft.Storage/storageAccounts@2021-06-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 při vytváření názvu prostředku účtu úložiště používá index i .

Další příklad nasadí modul několikrát.

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

Prvky pole

Následující příklad vytvoří jeden účet úložiště pro každý název zadaný v parametru storageNames . Všimněte si, že vlastnost name 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@2021-06-01' = [for name in storageNames: {
  name: '${name}${uniqueString(resourceGroup().id)}'
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'Storage'
}]

Další příklad iteruje pole a definuje vlastnost. Vytvoří dvě podsítě v rámci virtuální sítě. 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@2020-07-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@2021-06-01' = [for (config, i) in storageConfigurations: {
  name: '${storageAccountNamePrefix}${config.suffix}${i}'
  location: resourceGroup().location
  sku: {
    name: config.sku
  }
  kind: 'StorageV2'
}]

Další příklad používá jak prvky pole, tak index k výstupu informací o nových prostředcích.

param location string = resourceGroup().location
param orgNames array = [
  'Contoso'
  'Fabrikam'
  'Coho'
]

resource nsg 'Microsoft.Network/networkSecurityGroups@2020-06-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 Dictionary

K iteraci prvků v objektu slovníku použijte funkci items, která objekt převede na pole. Vlastnost použijte value 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@2020-06-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, který kolekci podmíněně nasadí.

Následující příklad ukazuje smyčku v kombinaci s příkazem podmínky. V tomto příkladu se na 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
  }
}]

Následující příklad ukazuje, jak použít podmínku, která je specifická pro aktuální prvek v poli.

resource parentResources 'Microsoft.Example/examples@2020-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ě. Pokud použijete smyčku k vytvoření více instancí typu prostředku, všechny tyto instance se nasadí najednou. Pořadí, ve kterém jsou vytvořeny, není zaručeno. Počet paralelně nasazených prostředků 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 rozmístit aktualizace tak, aby se v jednom okamžiku aktualizoval pouze určitý počet. Můžete určit, aby se podmnožina instancí seskupila do dávek a nasadila se současně. Ostatní instance čekají na dokončení této dávky.

Pokud chcete sériově nasadit instance prostředku, přidejte dekorátor batchSize. Nastavte jeho hodnotu na počet instancí, které se mají nasadit současně. 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@2021-06-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 tento dekorátor odlišit od jiné položky se stejným názvem, před tento dekorátor zadejte sys: @sys.batchSize(2)

Iterace pro podřízený prostředek

Smyčku nemůžete použít pro vnořený podřízený prostředek. Pokud chcete vytvořit více instancí podřízeného prostředku, změňte podřízený prostředek na prostředek nejvyšší úrovně.

Předpokládejme například, že obvykle definujete souborovou službu a sdílenou složku jako vnořené prostředky pro účet úložiště.

resource stg 'Microsoft.Storage/storageAccounts@2021-06-01' = {
  name: 'examplestorage'
  location: resourceGroup().location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
  resource service 'fileServices' = {
    name: 'default'
    resource share 'shares' = {
      name: 'exampleshare'
    }
  }
}

Pokud chcete vytvořit víc než jednu sdílenou složku, přesuňte ji mimo účet úložiště. Vztah s nadřazeným prostředkem definujete prostřednictvím parent vlastnosti .

Následující příklad ukazuje, jak vytvořit účet úložiště, souborovou službu a více než jednu sdílenou složku:

resource stg 'Microsoft.Storage/storageAccounts@2021-06-01' = {
  name: 'examplestorage'
  location: resourceGroup().location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}

resource service 'Microsoft.Storage/storageAccounts/fileServices@2021-06-01' = {
  name: 'default'
  parent: stg
}

resource share 'Microsoft.Storage/storageAccounts/fileServices/shares@2021-06-01' = [for i in range(0, 3): {
  name: 'exampleshare${i}'
  parent: service
}]

Další kroky

  • Pokud chcete nastavit závislosti na prostředcích vytvořených ve smyčce, projděte si téma Závislosti prostředků.