Bicep'te yinelemeli döngüler

Bu makalede, bir koleksiyondaki öğeleri yinelemek için söz diziminin for nasıl kullanılacağı gösterilmektedir. Bu işlev v0.3.1'den başlayarak desteklenir. Bir kaynağın, modülün, değişkenin, özelliğin veya çıkışın birden çok kopyasını tanımlamak için döngüleri kullanabilirsiniz. Bicep dosyanızda söz diziminin yinelenmesinden kaçınmak ve dağıtım sırasında oluşturulacak kopya sayısını dinamik olarak ayarlamak için döngüleri kullanın. Hızlı bir başlangıç yapmak için bkz . Hızlı Başlangıç: Birden çok örnek oluşturma.

Döngüleri kullanarak birden çok kaynak veya modül oluşturmak için her örneğin name özelliği için benzersiz bir değeri olmalıdır. Adları oluşturmak için dizin değerini veya dizilerdeki veya koleksiyonlardaki benzersiz değerleri kullanabilirsiniz.

Eğitim kaynakları

Adım adım yönergeler aracılığıyla döngüler hakkında bilgi edinmek isterseniz bkz . Koşulları ve döngüleri kullanarak esnek Bicep şablonları oluşturma.

Döngü söz dizimi

Döngüler şu şekilde bildirilebilir:

  • Tamsayı dizini kullanma. Senaryonuz şu olduğunda bu seçenek çalışır: "Bu kadar çok örnek oluşturmak istiyorum." range işlevi, başlangıç dizininde başlayan ve belirtilen öğelerin sayısını içeren bir tamsayı dizisi oluşturur. Döngü içinde, değerleri değiştirmek için tamsayı dizinini kullanabilirsiniz. Daha fazla bilgi için bkz . Tamsayı dizini.

    [for <index> in range(<startIndex>, <numberOfElements>): {
      ...
    }]
    
  • Dizideki öğeleri kullanma. Senaryonuz şu olduğunda bu seçenek çalışır: "Dizideki her öğe için bir örnek oluşturmak istiyorum." Döngü içinde, değerleri değiştirmek için geçerli dizi öğesinin değerini kullanabilirsiniz. Daha fazla bilgi için bkz . Dizi öğeleri.

    [for <item> in <collection>: {
      ...
    }]
    
  • Sözlük nesnesindeki öğeleri kullanma. Senaryonuz şu olduğunda bu seçenek çalışır: "Nesnedeki her öğe için bir örnek oluşturmak istiyorum." items işlevi nesneyi bir diziye dönüştürür. Döngü içinde, değer oluşturmak için nesnenin özelliklerini kullanabilirsiniz. Daha fazla bilgi için bkz . Sözlük nesnesi.

    [for <item> in items(<object>): {
      ...
    }]
    
  • Bir dizide tamsayı dizini ve öğeleri kullanma. Senaryonuz şu olduğunda bu seçenek çalışır: "Dizideki her öğe için bir örnek oluşturmak istiyorum, ancak başka bir değer oluşturmak için geçerli dizine de ihtiyacım var." Daha fazla bilgi için bkz . Döngü dizisi ve dizin.

    [for (<item>, <index>) in <collection>: {
      ...
    }]
    
  • Koşullu dağıtım ekleme. Senaryonuz şu olduğunda bu seçenek çalışır: "Birden çok örnek oluşturmak istiyorum, ancak her örnek için yalnızca bir koşul doğru olduğunda dağıtmak istiyorum." Daha fazla bilgi için bkz . Koşulla döngü yapma.

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

Döngü sınırları

Bicep'te döngüleri kullanmak şu sınırlamalara sahiptir:

  • Bicep döngüleri yalnızca dağıtımın başlangıcında belirlenebilecek değerlerle çalışır.
  • Döngü yinelemeleri negatif bir sayı olamaz veya 800 yinelemeyi aşamaz.
  • bir kaynağı iç içe alt kaynaklarla döngüye alınamaz. Alt kaynakları üst düzey kaynaklar olarak değiştirin. Bkz. Alt kaynak için yineleme.
  • Birden çok özellik düzeyinde döngü yapmak için lambda eşleme işlevini kullanın.

Tamsayı dizini

Dizin kullanmanın basit bir örneği için dize dizisi içeren bir değişken oluşturun.

param itemCount int = 5

var stringArray = [for i in range(0, itemCount): 'item${(i + 1)}']

output arrayResult array = stringArray

Çıkış, aşağıdaki değerlere sahip bir dizi döndürür:

[
  "item1",
  "item2",
  "item3",
  "item4",
  "item5"
]

Sonraki örnek, parametresinde storageCount belirtilen depolama hesabı sayısını oluşturur. Her depolama hesabı için üç özellik döndürür.

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

resource storageAcct 'Microsoft.Storage/storageAccounts@2022-09-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
}]

Depolama hesabı kaynak adını oluştururken dizinin i kullanıldığına dikkat edin.

Sonraki örnek bir modülü birden çok kez dağıtır.

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

Dizi öğeleri

Aşağıdaki örnek, parametresinde storageNames sağlanan her ad için bir depolama hesabı oluşturur. Her kaynak örneğinin name özelliğinin benzersiz olması gerektiğini unutmayın.

param location string = resourceGroup().location
param storageNames array = [
  'contoso'
  'fabrikam'
  'coho'
]

resource storageAcct 'Microsoft.Storage/storageAccounts@2022-09-01' = [for name in storageNames: {
  name: '${name}${uniqueString(resourceGroup().id)}'
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'Storage'
}]

Sonraki örnek, bir özelliği tanımlamak için bir dizi üzerinde yinelenir. Sanal ağ içinde iki alt ağ oluşturur. Alt ağ adlarının benzersiz olması gerektiğini unutmayı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
      }
    }]
  }
}

Dizi ve dizin

Aşağıdaki örnek, depolama hesabını tanımlarken hem dizi öğesini hem de dizin değerini kullanır.

param storageAccountNamePrefix string

var storageConfigurations = [
  {
    suffix: 'local'
    sku: 'Standard_LRS'
  }
  {
    suffix: 'geo'
    sku: 'Standard_GRS'
  }
]

resource storageAccountResources 'Microsoft.Storage/storageAccounts@2022-09-01' = [for (config, i) in storageConfigurations: {
  name: '${storageAccountNamePrefix}${config.suffix}${i}'
  location: resourceGroup().location
  sku: {
    name: config.sku
  }
  kind: 'StorageV2'
}]

Sonraki örnek, yeni kaynaklar hakkındaki bilgileri çıkarmak için hem dizinin öğelerini hem de dizini kullanır.

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

Sözlük nesnesi

Sözlük nesnesindeki öğeler üzerinde yineleme yapmak için, nesneyi diziye dönüştüren items işlevini kullanın. value Nesneleri özelliklerini almak için özelliğini kullanın. nsg kaynak adlarının benzersiz olması gerektiğini unutmayı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
}]

Koşul ile döngü

Kaynaklar ve modüller için, koleksiyonu koşullu olarak dağıtmak için döngü söz dizimine sahip bir if ifade ekleyebilirsiniz.

Aşağıdaki örnekte bir koşul deyimiyle birleştirilmiş bir döngü gösterilmektedir. Bu örnekte, modülün tüm örneklerine tek bir koşul uygulanır.

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

Sonraki örnekte dizideki geçerli öğeye özgü bir koşulun nasıl uygulanacağı gösterilmektedir.

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

Toplu olarak dağıtma

Varsayılan olarak, Azure kaynakları paralel olarak dağıtılır. Bir kaynak türünün birden çok örneğini oluşturmak için bir döngü kullandığınızda, bu örneklerin tümü aynı anda dağıtılır. Oluşturulma sırası garanti değildir. Bicep dosyasındaki toplam 800 kaynak sınırı dışında paralel olarak dağıtılan kaynak sayısıyla ilgili bir sınır yoktur.

Bir kaynak türünün tüm örneklerini aynı anda güncelleştirmek istemeyebilirsiniz. Örneğin, bir üretim ortamını güncelleştirirken, herhangi bir anda yalnızca belirli bir sayıyı güncelleştirmek için güncelleştirmeleri kademelendirin. Örneklerin bir alt kümesinin birlikte toplu işleneceğini ve aynı anda dağıtılacağını belirtebilirsiniz. Diğer örnekler bu toplu işlemin tamamlanmasını bekler.

Bir kaynağın örneklerini seri olarak dağıtmak için batchSize dekoratörünün eklenmesini sağlayın. Değerini eşzamanlı olarak dağıtılacak örnek sayısına ayarlayın. Döngüdeki önceki örneklerde bir bağımlılık oluşturulur, bu nedenle önceki toplu işlem tamamlanana kadar tek bir toplu işlem başlatmaz.

param location string = resourceGroup().location

@batchSize(2)
resource storageAcct 'Microsoft.Storage/storageAccounts@2022-09-01' = [for i in range(0, 4): {
  name: '${i}storage${uniqueString(resourceGroup().id)}'
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'Storage'
}]

Sıralı dağıtım için toplu iş boyutunu 1 olarak ayarlayın.

Dekoratör batchSize sys ad alanındadır. Bu dekoratörü aynı ada sahip başka bir öğeden ayırmanız gerekiyorsa, dekoratörün önüne sys yazın:@sys.batchSize(2)

Alt kaynak için yineleme

İç içe alt kaynak için döngü kullanamazsınız. Bir alt kaynağın birden fazla örneğini oluşturmak için alt kaynağı üst düzey bir kaynak olarak değiştirin.

Örneğin, genellikle bir dosya hizmeti ve dosya paylaşımını depolama hesabı için iç içe kaynaklar olarak tanımladığınız varsayılır.

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

Birden fazla dosya paylaşımı oluşturmak için depolama hesabının dışına taşıyın. Üst kaynakla ilişkiyi özelliği aracılığıyla parent tanımlarsınız.

Aşağıdaki örnekte depolama hesabı, dosya hizmeti ve birden çok dosya paylaşımının nasıl oluşturulacağı gösterilmektedir:

resource stg 'Microsoft.Storage/storageAccounts@2022-09-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
}]

Kaynak/modül koleksiyonları başvurusu

ARM şablonu references işlevi, kaynak koleksiyonunun çalışma zamanı durumlarını temsil eden bir nesne dizisi döndürür. Bicep'te açık başvuru işlevi yoktur. Bunun yerine, sembolik koleksiyon kullanımı doğrudan kullanılır ve kod oluşturma sırasında Bicep bunu ARM şablonu başvuruları işlevini kullanan bir ARM şablonuna çevirir. References işlevini kullanarak sembolik koleksiyonları ARM şablonlarına dönüştüren çeviri özelliği için Bicep CLI sürüm 0.20.X veya üzeri olması gerekir. Ayrıca, dosyada bicepconfig.jsonsymbolicNameCodegen ayar sunulmalı ve olarak trueayarlanmalıdır.

Integer dizinindeki iki örneğin çıkışları şöyle yazılabilir:

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

resource storageAcct 'Microsoft.Storage/storageAccounts@2022-09-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)

Bu Bicep dosyası, işlevini kullanan aşağıdaki ARM JSON şablonuna references dönüştürülür:

{
  "$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": "2022-09-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))]"
    }
  }
}

Yukarıdaki ARM JSON şablonunda, languageVersion olarak ayarlanması 1.10-experimentalgerektiğini ve kaynak öğesinin dizi yerine bir nesne olduğunu unutmayın.

Sonraki adımlar

  • Bicep dosyaları oluşturma hakkında bilgi edinmek için bkz . dosya.