使用循环部署多个资源

已完成

通常你需要部署多个非常相似的资源。 通过将循环添加到 Bicep 文件,可以避免重复执行资源定义。 相反,可以动态地设置要部署的资源的实例数。 甚至可以自定义每个实例的属性。

对于你所在的玩具公司来说,你需要部署后端基础结构(包括一些 Azure SQL 逻辑服务器)以支持推出新的智能小熊。 你需要将专用逻辑服务器部署到提供该玩具的每个国家/地区,以便遵守每个国家/地区的数据保护法律。

除了位置之外,所有逻辑服务器都将以相同的方式进行配置。 你需要使用 Bicep 代码来部署逻辑服务器,并且应能通过一个参数指定逻辑服务器应部署到的区域。

本单元将介绍如何使用复制循环部署多个资源实例。

注意

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

使用复制循环

在 Bicep 模板中定义资源或模块时,可以使用 for 关键字创建循环。 将 for 关键字放在资源声明中,然后指定希望 Bicep 标识循环中的每一项的方法。 通常,你会循环访问对象的数组以创建多个资源实例。 以下示例将部署多个存储帐户,其名称被指定为参数值:

param storageAccountNames array = [
  'saauditus'
  'saauditeurope'
  'saauditapac'
]

resource storageAccountResources 'Microsoft.Storage/storageAccounts@2021-09-01' = [for storageAccountName in storageAccountNames: {
  name: storageAccountName
  location: resourceGroup().location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}]

在此示例中,循环会循环访问 storageAccountNames 数组中的每个项。 Bicep 在每次遍历循环时,会将当前值放入名为 storageAccountName 的特殊变量中,并用作 name 属性的值。 请注意,Bicep 要求在 for 关键字之前放置一个左括号 ([) 字符,在资源定义之后放置一个右括号 (]) 字符。

如果已部署此 Bicep 文件,你会看到已创建三个存储帐户,其名称由 storageAccountNames 数组中的相应项指定。

基于计数的循环

有时可能需要使用循环来创建特定数量的资源,而不是使用数组作为源。 Bicep 提供 range() 函数,用于创建数字数组。 例如,如果你需要通过 sa4 创建四个名为 sa1 的存储帐户,则可以使用如下所示的资源定义:

resource storageAccountResources 'Microsoft.Storage/storageAccounts@2021-09-01' = [for i in range(1,4): {
  name: 'sa${i}'
  location: resourceGroup().location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}]

使用 range() 函数时,可以指定其起始值和你要创建的值的数量。 例如,如果要创建名称为 sa0sa1sa2 的存储帐户,则使用函数 range(0,3)

注意

使用 range() 函数时,需要提供两个自变量。 第一个自变量指定起始值,第二个自变量告诉 Bicep 你需要的值的数量。 例如,如果你使用 range(3,4),则 Bicep 将返回值 3456。 请确保请求正确的值数量,尤其是在使用起始值 0 时。

访问迭代索引

使用 Bicep,可以循环访问数组并检索数组中当前元素的索引。 例如,假设你要在数组指定的每个位置创建一个逻辑服务器,并且要让服务器的名称为 sqlserver-1sqlserver-2 等等。 可以使用以下 Bicep 代码来实现:

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

resource sqlServers 'Microsoft.Sql/servers@2021-11-01-preview' = [for (location, i) in locations: {
  name: 'sqlserver-${i+1}'
  location: location
  properties: {
    administratorLogin: administratorLogin
    administratorLoginPassword: administratorLoginPassword
  }
}]

请注意,name 属性包含表达式 i+1i 索引变量的第一个值为零,因此,如果你需要让服务器名称从 1 开始,需要向其添加 +1

提示

在本示例中,我们将索引变量命名为 i。 这是 Bicep 中的标准约定。 不过,你可以使用任何名称。

使用循环筛选项

在某些情况下,可能需要结合使用复制循环和条件来部署资源。 可以通过组合使用 iffor 关键字来实现。

在下面的示例中,代码使用数组参数来定义一组逻辑服务器。 条件与复制循环一起使用,以便仅在循环对象的 environmentName 属性等于 Production 时部署服务器:

param sqlServerDetails array = [
  {
    name: 'sqlserver-we'
    location: 'westeurope'
    environmentName: 'Production'
  }
  {
    name: 'sqlserver-eus2'
    location: 'eastus2'
    environmentName: 'Development'
  }
  {
    name: 'sqlserver-eas'
    location: 'eastasia'
    environmentName: 'Production'
  }
]

resource sqlServers 'Microsoft.Sql/servers@2021-11-01-preview' = [for sqlServer in sqlServerDetails: if (sqlServer.environmentName == 'Production') {
  name: sqlServer.name
  location: sqlServer.location
  properties: {
    administratorLogin: administratorLogin
    administratorLoginPassword: administratorLoginPassword
  }
  tags: {
    environment: sqlServer.environmentName
  }
}]

如果部署了前面的示例,将会看到两个逻辑服务器 sqlserver-wesqlserver-eas,但看不到 sqlserver-eus2,因为该对象的 environmentName 属性与 Production 不匹配。