控制循环执行和嵌套循环
通过使用强大的复制循环功能,可以创建动态且灵活的模板。 请务必了解如何控制循环在创建资源时的执行方式,以及如何使用循环来设置资源属性和嵌套循环。
在本单元中,你将学习如何控制复制循环的执行,以及如何在 Bicep 中使用资源属性循环和嵌套循环。
注意
本单元中显示的命令用于说明概念。 请暂时不要运行这些命令。 稍后你将练习在此处学到的知识。
控制循环执行
默认情况下,Azure 资源管理器以非确定性顺序从循环中并行地创建资源。 在上一个练习中创建循环时,两个 Azure SQL 逻辑服务器是同时创建的。 这有助于缩短总体部署时间,因为循环内的所有资源都是一次部署的。
但是,在某些情况下,可能需要按顺序(而不是并行地)在循环中部署资源,或者并行部署少量更改。 例如,如果生产环境中有大量 Azure 应用服务应用,你可能希望一次仅将更改部署到一小部分,以防止更新同时重启所有应用。
可以使用 @batchSize
修饰器控制复制循环在 Bicep 中的运行方式。 使用 for
关键字将修饰器放在资源或模块声明上。
让我们看看没有 @batchSize
修饰器的一组应用服务应用程序的示例 Bicep定义:
resource appServiceApp 'Microsoft.Web/sites@2023-12-01' = [for i in range(1,3): {
name: 'app${i}'
// ...
}]
此循环中的所有资源将同时并行部署:
现在,应用值为 2
的 @batchSize
修饰器:
@batchSize(2)
resource appServiceApp 'Microsoft.Web/sites@2023-12-01' = [for i in range(1,3): {
name: 'app${i}'
// ...
}]
当你部署模板时,Bicep 将分两批部署:
注意
Bicep 将等待每个完整的批次完成,然后再继续下一个批次。 在上面的示例中,如果 app2 在 app1 之前完成其部署,Bicep 将等待 app1 完成,然后再开始部署 app3。
你还可以将 @batchSize
设置为 1
,让 Bicep 按顺序运行循环:
@batchSize(1)
resource appServiceApp 'Microsoft.Web/sites@2023-12-01' = [for i in range(1,3): {
name: 'app${i}'
// ...
}]
当你部署模板时,Bicep 会等待每个资源部署完成,然后再开始下一个资源部署:
将循环与资源属性一起使用
可以使用循环来帮助设置资源属性。 例如,当你部署虚拟网络时,需要指定其子网。 子网必须包含两条重要信息:名称和地址前缀。 可以将参数与对象数组一起使用,为每个环境指定不同的子网:
param subnetNames array = [
'api'
'worker'
]
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = {
name: 'teddybear'
location: resourceGroup().location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: [for (subnetName, i) in subnetNames: {
name: subnetName
properties: {
addressPrefix: '10.0.${i}.0/24'
}
}]
}
}
请注意,本示例中的 for
循环出现在资源定义中,位于 subnets
属性值周围。
嵌套循环
某些场景要求在另一个循环内使用循环,即嵌套循环。 可以使用 Bicep 创建嵌套循环。
对于你所在的小熊玩具公司,你需要在将推出玩具的每个国家/地区部署虚拟网络。 每个虚拟网络都需要不同的地址空间,并需要两个子网。 首先,在循环中部署虚拟网络:
param locations array = [
'westeurope'
'eastus2'
'eastasia'
]
var subnetCount = 2
resource virtualNetworks 'Microsoft.Network/virtualNetworks@2024-01-01' = [for (location, i) in locations : {
name: 'vnet-${location}'
location: location
properties: {
addressSpace:{
addressPrefixes:[
'10.${i}.0.0/16'
]
}
}
}]
此循环为每个位置部署了虚拟网络,并且使用循环索引为虚拟网络设置 addressPrefix
,以确保每个虚拟网络都获取不同的地址前缀。
可以使用嵌套循环在每个虚拟网络中部署子网:
resource virtualNetworks 'Microsoft.Network/virtualNetworks@2024-01-01' = [for (location, i) in locations : {
name: 'vnet-${location}'
location: location
properties: {
addressSpace:{
addressPrefixes:[
'10.${i}.0.0/16'
]
}
subnets: [for j in range(1, subnetCount): {
name: 'subnet-${j}'
properties: {
addressPrefix: '10.${i}.${j}.0/24'
}
}]
}
}]
嵌套循环使用 range()
函数创建两个子网。
当你部署模板时,将获取以下虚拟网络和子网:
虚拟网络名称 | 位置 | 地址前缀 | 子网 |
---|---|---|---|
vnet-westeurope |
westeurope |
10.0.0.0/16 |
10.0.1.0/24 、10.0.2.0/24 |
vnet-eastus2 |
eastus2 |
10.1.0.0/16 |
10.1.1.0/24 、10.1.2.0/24 |
vnet-eastasia |
eastasia |
10.2.0.0/16 |
10.2.1.0/24 、10.2.2.0/24 |