ARM模板使用mul函数组合数组生成私有端点时索引越界问题
解决ARM模板部署CosmosDB多私有端点的索引越界问题
问题核心是单层copy循环中,直接用copyIndex()作为数组索引会超出vnetArray或subnetArray的长度范围。正确的做法是通过除法取整和取模运算,将全局的copyIndex()映射到对应的VNet和子网索引。
关键逻辑
- 总实例数:用
mul(length(vnetArray), length(subnetArray))计算,这里是5*4=20,这个逻辑是正确的。 - VNet索引:
div(copyIndex(), length(subnetArray))——每length(subnetArray)个实例对应一个VNet,除法取整得到当前实例所属的VNet在数组中的位置。 - 子网索引:
mod(copyIndex(), length(subnetArray))——取模运算得到当前实例在对应VNet下的子网索引。
完整模板示例
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "cosmosDbAccountName": { "type": "string" }, "vnetArray": { "type": "array", "defaultValue": [ {"name": "vnet-1", "resourceGroup": "rg-vnet-1"}, {"name": "vnet-2", "resourceGroup": "rg-vnet-2"}, {"name": "vnet-3", "resourceGroup": "rg-vnet-3"}, {"name": "vnet-4", "resourceGroup": "rg-vnet-4"}, {"name": "vnet-5", "resourceGroup": "rg-vnet-5"} ] }, "subnetArray": { "type": "array", "defaultValue": [ {"name": "subnet-a"}, {"name": "subnet-b"}, {"name": "subnet-c"}, {"name": "subnet-d"} ] } }, "resources": [ { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-05-01", "name": "[concat(parameters('subnetArray')[mod(copyIndex(), length(parameters('subnetArray')))].name, '-', take(parameters('vnetArray')[div(copyIndex(), length(parameters('subnetArray')))].name, 5), '-privateendpoint')]", "location": "[resourceGroup().location]", "copy": { "name": "privateEndpointCopy", "count": "[mul(length(parameters('vnetArray')), length(parameters('subnetArray')))]" }, "properties": { "privateLinkServiceConnections": [ { "name": "[concat(parameters('cosmosDbAccountName'), '-plsc')]", "properties": { "privateLinkServiceId": "[resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosDbAccountName'))]", "groupIds": ["Sql"] } } ], "subnet": { "id": "[resourceId(parameters('vnetArray')[div(copyIndex(), length(parameters('subnetArray')))].resourceGroup, 'Microsoft.Network/virtualNetworks/subnets', parameters('vnetArray')[div(copyIndex(), length(parameters('subnetArray')))].name, parameters('subnetArray')[mod(copyIndex(), length(parameters('subnetArray')))].name)]" } } } ] }
说明
- 命名规则:示例中用
子网名称-VNet前5个字符-privateendpoint生成类似subnet-a-vnet-1-privateendpoint的唯一名称,你可以根据需求调整(比如加入随机字符串或固定后缀)。 - 索引计算验证:
- 当
copyIndex()为0:div(0,4)=0(取vnetArray[0]),mod(0,4)=0(取subnetArray[0]) - 当
copyIndex()为4:div(4,4)=1(取vnetArray[1]),mod(4,4)=0(取subnetArray[0]) - 以此类推,所有20个实例都会正确映射到对应的VNet和子网,不会出现索引越界。
- 当
- 子网ID拼接:通过
resourceId函数结合VNet的资源组、VNet名称和子网名称,正确引用子网资源。
内容的提问来源于stack exchange,提问作者Zucoa
相关产品推荐
相关产品推荐

