How would I do a two dimensional loop to enumerate vnet pairs? #14762
-
I'm trying to do something like this in order to peer a list of vnet peers // Parameters
param locations array = [
{ name: 'East US', sname: 'eus' }
{ name: 'West US', sname: 'wus' }
{ name: 'Central US', sname: 'cus' }
]
param vnetNamePrefix string = 'vnet'
resource vnets 'Microsoft.Network/virtualNetworks@2020-11-01' existing = [for (location, i) in locations: {
name: '${vnetNamePrefix}-${locations[i].sname}'
}]
resource vnetPeerings 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2020-11-01' = [for (vnet1, i) in vnets: [for (vnet2, j) in vnets: if (i != j) {
name: '${vnets[i].name}-to-${vnets[j].name}'
parent: vnets[i]
properties: {
remoteVirtualNetwork: {
id: vnets[j].id
}
allowVirtualNetworkAccess: true
allowForwardedTraffic: true
allowGatewayTransit: false
useRemoteGateways: false
}
}]] I get this error, Is there a way to express this? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Nested loops are not supported by bicep. There is also the issue mentioned in the error which is different from the unsupported two dimensional loops. For the BCP144, add a {
"analyzers": {
"core": {
"rules": {
"no-unused-params": {
"level": "warning"
}
}
}
},
"experimentalFeaturesEnabled": {
"symbolicNameCodegen": true
}
} And loop over resources/modules using the
For the second issue, using modules wouldn't be too hard.
param vnetNamePrefix string = 'vnet'
// Parameters
param location string
resource vnets 'Microsoft.Network/virtualNetworks@2020-11-01' existing = {
name: '${vnetNamePrefix}-${location}'
}
type vnetOutputObject = {
name: string
id: string
}
output vnetsOutput vnetOutputObject = {
name: vnets.name
id: vnets.id
}
param locations array = [
{ name: 'East US', sname: 'eus' }
{ name: 'West US', sname: 'wus' }
{ name: 'Central US', sname: 'cus' }
]
param vnetNamePrefix string = 'vnet'
module vnets './module1.bicep' = [for location in locations: {
name: location.sname
params: {
location: location.sname
vnetNamePrefix: vnetNamePrefix
}
}]
var retrievedVnets = map(vnets, vnet => {
name: vnet.outputs.vnetsOutput.name
id: vnet.outputs.vnetsOutput.id
})
output retrievedVnetsOutput array = retrievedVnets
param vnets object[]
var vnetPeeringsArray = [for (vnet, i) in vnets: map(vnets, (vnet2, j) => i == j ? {} : {
sourceName: vnet.name
destinationName: vnet2.name
destinationId: vnet2.id
})]
var flattenedVnetPeeringsArray = filter(flatten(vnetPeeringsArray), peering => peering != {})
module deployVnetPeerings 'module4.bicep' = [for vnetPeering in flattenedVnetPeeringsArray: {
name: 'deployVnetPeerings${vnetPeering.sourceName}-${vnetPeering.destinationName}'
params: {
destinationVnetId: vnetPeering.destinationId
destinationVnetName: vnetPeering.destinationName
sourceVnetName: vnetPeering.sourceName
}
}]
output vnetPeeringsArray array = flattenedVnetPeeringsArray
param sourceVnetName string
param destinationVnetName string
param destinationVnetId string
resource vnetParent 'Microsoft.Network/virtualNetworks@2024-01-01' = {
name: sourceVnetName
resource vnetPeerings 'virtualNetworkPeerings@2020-11-01' = {
name: '${sourceVnetName}-to-${destinationVnetName}'
properties: {
remoteVirtualNetwork: {
id: destinationVnetId
}
allowVirtualNetworkAccess: true
allowForwardedTraffic: true
allowGatewayTransit: false
useRemoteGateways: false
}
}
}
// Parameters
param locations array = [
{ name: 'East US', sname: 'eus' }
{ name: 'West US', sname: 'wus' }
{ name: 'Central US', sname: 'cus' }
]
param vnetNamePrefix string = 'vnet'
module vnets 'module2.bicep' = {
name: 'vnets'
params: {
locations: locations
vnetNamePrefix: vnetNamePrefix
}
}
module vnetPeerings './module3.bicep' = {
name: 'vnetPeerings'
params: {
vnets: vnets.outputs.retrievedVnetsOutput
}
} It should then compile to something like this: {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
"templateHash": "4087662148066534679"
}
},
"parameters": {
"locations": {
"type": "array",
"defaultValue": [
{
"name": "East US",
"sname": "eus"
},
{
"name": "West US",
"sname": "wus"
},
{
"name": "Central US",
"sname": "cus"
}
]
},
"vnetNamePrefix": {
"type": "string",
"defaultValue": "vnet"
}
},
"resources": {
"vnets": {
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "vnets",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"locations": {
"value": "[parameters('locations')]"
},
"vnetNamePrefix": {
"value": "[parameters('vnetNamePrefix')]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
"templateHash": "6247077611319919796"
}
},
"parameters": {
"locations": {
"type": "array",
"defaultValue": [
{
"name": "East US",
"sname": "eus"
},
{
"name": "West US",
"sname": "wus"
},
{
"name": "Central US",
"sname": "cus"
}
]
},
"vnetNamePrefix": {
"type": "string",
"defaultValue": "vnet"
}
},
"resources": {
"vnets": {
"copy": {
"name": "vnets",
"count": "[length(parameters('locations'))]"
},
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "[parameters('locations')[copyIndex()].name]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"location": {
"value": "[parameters('locations')[copyIndex()]]"
},
"vnetNamePrefix": {
"value": "[parameters('vnetNamePrefix')]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
"templateHash": "10789138844429073944"
}
},
"definitions": {
"vnetOutputObject": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"id": {
"type": "string"
}
}
}
},
"parameters": {
"vnetNamePrefix": {
"type": "string",
"defaultValue": "vnet"
},
"location": {
"type": "object"
}
},
"resources": {
"vnets": {
"existing": true,
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-11-01",
"name": "[format('{0}-{1}', parameters('vnetNamePrefix'), parameters('location'))]"
}
},
"outputs": {
"vnetsOutput": {
"$ref": "#/definitions/vnetOutputObject",
"value": {
"name": "[format('{0}-{1}', parameters('vnetNamePrefix'), parameters('location'))]",
"id": "[resourceId('Microsoft.Network/virtualNetworks', format('{0}-{1}', parameters('vnetNamePrefix'), parameters('location')))]"
}
}
}
}
}
}
},
"outputs": {
"retrievedVnetsOutput": {
"type": "array",
"value": "[map(references('vnets'), lambda('vnet', createObject('name', lambdaVariables('vnet').outputs.vnetsOutput.value.name, 'id', lambdaVariables('vnet').outputs.vnetsOutput.value.id)))]"
}
}
}
}
},
"vnetPeerings": {
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "vnetPeerings",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"vnets": {
"value": "[reference('vnets').outputs.retrievedVnetsOutput.value]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
"templateHash": "17817991671013892942"
}
},
"parameters": {
"vnets": {
"type": "array",
"items": {
"type": "object"
}
}
},
"variables": {
"copy": [
{
"name": "vnetPeeringsArray",
"count": "[length(parameters('vnets'))]",
"input": "[map(parameters('vnets'), lambda('vnet2', 'j', if(equals(copyIndex('vnetPeeringsArray'), lambdaVariables('j')), createObject(), createObject('sourceName', parameters('vnets')[copyIndex('vnetPeeringsArray')].name, 'destinationName', lambdaVariables('vnet2').name, 'destinationId', lambdaVariables('vnet2').id))))]"
}
],
"flattenedVnetPeeringsArray": "[filter(flatten(variables('vnetPeeringsArray')), lambda('peering', not(equals(lambdaVariables('peering'), createObject()))))]"
},
"resources": {
"deployVnetPeerings": {
"copy": {
"name": "deployVnetPeerings",
"count": "[length(variables('flattenedVnetPeeringsArray'))]"
},
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "[format('deployVnetPeerings{0}-{1}', variables('flattenedVnetPeeringsArray')[copyIndex()].sourceName, variables('flattenedVnetPeeringsArray')[copyIndex()].destinationName)]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"destinationVnetId": {
"value": "[variables('flattenedVnetPeeringsArray')[copyIndex()].destinationId]"
},
"destinationVnetName": {
"value": "[variables('flattenedVnetPeeringsArray')[copyIndex()].destinationName]"
},
"sourceVnetName": {
"value": "[variables('flattenedVnetPeeringsArray')[copyIndex()].sourceName]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.28.1.47646",
"templateHash": "9576906321766851887"
}
},
"parameters": {
"sourceVnetName": {
"type": "string"
},
"destinationVnetName": {
"type": "string"
},
"destinationVnetId": {
"type": "string"
}
},
"resources": {
"vnetParent::vnetPeerings": {
"type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings",
"apiVersion": "2020-11-01",
"name": "[format('{0}/{1}', parameters('sourceVnetName'), format('{0}-to-{1}', parameters('sourceVnetName'), parameters('destinationVnetName')))]",
"properties": {
"remoteVirtualNetwork": {
"id": "[parameters('destinationVnetId')]"
},
"allowVirtualNetworkAccess": true,
"allowForwardedTraffic": true,
"allowGatewayTransit": false,
"useRemoteGateways": false
},
"dependsOn": [
"vnetParent"
]
},
"vnetParent": {
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2024-01-01",
"name": "[parameters('sourceVnetName')]"
}
}
}
}
}
},
"outputs": {
"vnetPeeringsArray": {
"type": "array",
"value": "[variables('flattenedVnetPeeringsArray')]"
}
}
}
},
"dependsOn": [
"vnets"
]
}
}
} |
Beta Was this translation helpful? Give feedback.
Nested loops are not supported by bicep. There is also the issue mentioned in the error which is different from the unsupported two dimensional loops.
For the BCP144, add a
bicepconfig.json
file to the root directory with the following content:And loop over resources/modules using the
map
function. This is because: