使用变量和输出循环

已完成

你已了解如何使用复制循环部署多个资源实例,以及如何使用循环设置资源的属性。 在 Bicep 中,还可以将循环与变量和输出一起使用。

对于玩具公司,你需要在多个 Azure 区域中部署子网配置相同的虚拟网络。 你预计将来需要向虚拟网络添加其他子网,因此需要使 Bicep 模板能够灵活地修改子网配置。

由于还将在 Azure 环境中部署多个存储帐户,因此你需要为每个存储帐户提供终结点作为输出,让部署管道可以使用此信息。

本单元介绍了如何将循环与变量和输出一起使用。

注意

本单元中显示的命令用于说明概念。 请暂时不要运行这些命令。 稍后你将练习在此处学到的知识。

变量循环

使用变量循环,可以创建一个数组,然后可以在 Bicep 文件中使用该数组。 与其他循环一样,可以使用 for 关键字创建一个变量循环:

var items = [for i in range(1, 5): 'item${i}']

前面的示例创建一个数组,其中包含 item1item2item3item4item5 值。

你通常会使用变量循环来创建更复杂的对象,然后可以在资源声明中使用这些对象。 下面的代码演示如何使用变量循环来创建 subnets 属性:

param addressPrefix string = '10.10.0.0/16'
param subnets array = [
  {
    name: 'frontend'
    ipAddressRange: '10.10.0.0/24'
  }
  {
    name: 'backend'
    ipAddressRange: '10.10.1.0/24'
  }
]

var subnetsProperty = [for subnet in subnets: {
  name: subnet.name
  properties: {
    addressPrefix: subnet.ipAddressRange
  }
}]

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-08-01' = {
  name: 'teddybear'
  location: resourceGroup().location
  properties:{
    addressSpace:{
      addressPrefixes:[
        addressPrefix
      ]
    }
    subnets: subnetsProperty
  }
}

本示例演示了变量循环的一种有效用途:将具有简单、易于理解的值的参数转换为一个与 Azure 资源的所需定义相对应的更复杂对象。 你可以使用变量循环来支持参数仅指定将更改列表中每个项的关键信息。 然后,可以使用 Bicep 表达式或默认值来设置资源的其他必需属性。

输出循环

你可以使用 Bicep 输出将部署的信息提供回启动部署的用户或工具。 输出循环可以提供输出中循环的灵活性和功能。

与使用其他循环时一样,请使用 for 关键字指定输出循环:

var items = [
  'item1'
  'item2'
  'item3'
  'item4'
  'item5'
]

output outputItems array = [for i in range(0, length(items)): items[i]]

通常可以将输出循环与模板内的其他循环结合使用。 例如,来看一个 Bicep 文件,该文件将一组存储帐户部署到由 locations 参数指定的 Azure 区域:

param locations array = [
  'westeurope'
  'eastus2'
  'eastasia'
]

resource storageAccounts 'Microsoft.Storage/storageAccounts@2021-09-01' = [for location in locations: {
  name: 'toy${uniqueString(resourceGroup().id, location)}'
  location: location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}]

你可能需要返回已创建的每个存储帐户的相关信息,例如其名称和可用于访问它的终结点。 使用输出循环,可以在 Bicep 文件中检索此信息。

备注

目前,Bicep 不支持从输出循环内直接引用在循环中创建的资源。 这意味着,你需要使用数组索引器来访问资源,如下一个示例所示。

output storageEndpoints array = [for i in range(0, length(locations)): {
  name: storageAccounts[i].name
  location: storageAccounts[i].location
  blobEndpoint: storageAccounts[i].properties.primaryEndpoints.blob
  fileEndpoint: storageAccounts[i].properties.primaryEndpoints.file
}]

注意

请勿使用输出返回机密,例如访问密钥或密码。 输出将会被记录下来,而且它们并不是为处理安全数据而设计的。