本文演示如何使用 for 语法来循环访问集合中的项。 此功能在 v0.3.1 及更高版本中可用。 可以使用循环来定义资源、模块、变量、属性或输出的多个副本。 使用循环可以避免在 Bicep 文件中重复语法,并可以动态设置要在部署期间创建的副本数。 若要完成快速入门,请参阅 快速入门:创建多个实例

若要使用循环创建多个资源或模块,每个实例必须具有唯一的名称属性值。 可以使用数组或集合中的索引值或唯一值来创建名称。

如果希望通过分步指导了解循环,请参阅 使用条件和循环生成灵活的 Bicep 模板

循环可以使用以下方式声明:

  • 使用整数索引。 当场景为“我想创建这么多实例”时,此选项适用。 range 函数 创建整数数组,该数组从起始索引开始并包含指定元素的数量。 在循环中,可以使用整数索引来修改值。 有关详细信息,请参阅 整数索引

    [for <index> in range(<startIndex>, <numberOfElements>): {
    
  • 使用数组中的项。 当场景为“我想要为数组中的每个元素创建实例”时,此选项适用。在循环中,可以使用当前数组元素值修改值。 有关详细信息,请参阅数组元素

    [for <item> in <collection>: {
    
  • 使用字典对象中的项。 当场景为“我想要为对象中的每个项创建实例”时,此选项适用。项函数可将对象转换为数组。 在循环中,可以使用对象中的属性来创建值。 有关详细信息,请参阅 字典对象

    [for <item> in items(<object>): {
    
  • 使用整数索引和数组中的项。 当场景为“我想要为数组中每个元素创建实例,但还需要当前索引来创建另一个值”时,此选项适用。有关详细信息,请参阅循环数组和索引

    [for (<item>, <index>) in <collection>: {
    
  • 添加条件部署。 当场景为“我想要创建多个实例,但对于每个实例,我希望仅在条件为真时进行部署”时,此选项适用。有关详细信息,请参阅带条件的循环

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

    在 Bicep 中使用循环有以下限制:

  • Bicep 循环仅适用于可在部署开始时确定的值。
  • 循环迭代不能为负数,也不能超过 800 次迭代。
  • 不能循环带有嵌套子资源的资源。 必须将子资源更改为顶级资源。 请参阅子资源的迭代
  • 若要在多个属性级别上循环,请使用 lambda 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@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
    

    请注意,创建存储帐户资源名称时将使用索引 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
    

    以下示例为 storageNames 参数中提供的每个名称创建一个存储帐户。 请注意,每个资源实例的名称属性必须独一无二。

    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'
    

    下一个示例将循环访问数组以定义属性。 它将在虚拟网络内创建两个子网。 请注意,子网名称必须独一无二。

    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

    数组和索引

    以下示例在定义存储帐户时使用数组元素和索引值。

    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'
    

    下一个示例使用数组元素和索引来输出有关新资源的信息。

    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
    

    要在字典对象中循环访问元素,请使用 items 函数,该函数会将对象转换为数组。 请使用 value 属性获取对象的属性。 请注意,nsg 资源名称必须独一无二。

    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
    

    带条件的循环

    对于资源和模块,可以在循环语法中添加 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@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
    

    默认情况下,将并行部署 Azure 资源。 使用循环创建多个资源类型实例时,将同时部署这些实例。 不会保证它们的创建顺序。 除了 Bicep 文件中的资源总数为 800 这一限制外,并行部署的资源数量没有限制。

    你可能不希望同时更新资源类型的所有实例。 例如,在更新生产环境时,可能需要错开更新,使任何一次仅更新一定数量。 可指定同时批处理和部署其中一部分实例。 其他实例等待该批处理完成。

    若要串行部署资源的实例,请添加 batchSize 修饰器。 将其值设置为要并发部署的实例数。 在循环中创建先前实例的依赖关系,使其在上一个批处理完成后才启动批处理。

    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'
    

    对于顺序部署,请将批大小设置为 1。

    batchSize 修饰器位于 sys 命名空间中。 如果你需要将此装饰器与同名的其他项区分开来,请在修饰器前面加上 sys:@sys.batchSize(2)

    子资源的迭代

    不能对嵌套子资源使用循环。 若要创建子资源的多个实例,请将子资源更改为顶级资源。

    例如,假设通常将文件服务和文件共享定义为存储帐户的嵌套资源。

    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'
    

    若要创建多个文件共享,请将其移到存储帐户之外。 可通过 parent 属性定义与父资源的关系。

    以下示例演示如何创建存储帐户、文件服务和多个文件共享:

    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
    
  • 要对循环中创建的资源设置依赖关系,请参阅资源依赖项
  •