I'm trying to create a json object that holds multiple Network Security Groups (NSG), in order to build them and apply to vNet subnets using "count" to minimize the template code. The Microsoft Documentation covers how to create an object for one NSG's settings under the "Using a property object in a copy loop" section. This would require me to create a new parameter object for each NSG I need, and lengthy template code for each NSG.
I'm currently using the following parameter object to hold all information about a Virtual network including the NSGs. NSGs will be tied to subnets, with the first subnet "GatewaySubnet" being excluded from needing a NSG
"vNetProperties": {
"value": {
"vNetAddressSpace": "10.136.0.0/16",
"subnetNames": [
"GatewaySubnet",
"Kemp-frontend-subnet",
"AD-backend-subnet"
],
"subnetRanges": [
"10.136.0.0/27",
"10.136.1.0/24",
"10.136.2.0/24"
],
"networkSecurityGroups": {
"value": {
"kempNSG": {
"value": {
"securityRules": [
{
"name": "HTTPS",
"description": "allow HTTPS connections",
"direction": "Inbound",
"priority": 100,
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "10.0.0.0/24",
"sourcePortRange": "*",
"destinationPortRange": "443",
"access": "Allow",
"protocol": "Tcp"
},
{
"name": "HTTP",
"description": "allow HTTP connections",
"direction": "Inbound",
"priority": 100,
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "10.0.0.0/24",
"sourcePortRange": "*",
"destinationPortRange": "80",
"access": "Allow",
"protocol": "Tcp"
}
]
}
},
"adNSG": {
"value": {
"securityRules": [
{
"name": "RDPAllow",
"description": "allow RDP connections",
"direction": "Inbound",
"priority": 100,
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "10.0.0.0/24",
"sourcePortRange": "*",
"destinationPortRange": "3389",
"access": "Allow",
"protocol": "Tcp"
}
]
}
}
}
}
}
}
My template code to process the object is as follows:
{
"apiVersion": "2016-06-01",
"type": "Microsoft.Network/networkSecurityGroups",
"name": "[concat(parameters('vNetProperties').subnetNames[copyIndex(1)], '-nsg')]",
"location": "[resourceGroup().location]",
"copy": {
"name": "NSGs",
"count": "[length(array(parameters('vNetProperties').networkSecurityGroups))]"
},
"properties": {
"copy": [
{
"name": "securityRules",
"count": "[length(array(parameters('vNetProperties').networkSecurityGroups[copyIndex('securityRules')]))]",
"input": {
"description": "[parameters('vNetProperties').networkSecurityGroups[0].securityRules[0].description]",
"priority": "[parameters('vNetProperties').networkSecurityGroups[copyIndex('NSGs')].securityRules[copyIndex('securityRules')].priority]",
"protocol": "[parameters('vNetProperties').networkSecurityGroups[copyIndex('NSGs')].securityRules[copyIndex('securityRules')].protocol]",
"sourcePortRange": "[parameters('vNetProperties').networkSecurityGroups[copyIndex('NSGs')].securityRules[copyIndex('securityRules')].sourcePortRange]",
"destinationPortRange": "[parameters('vNetProperties').networkSecurityGroups[copyIndex('NSGs')].securityRules[copyIndex('securityRules')].destinationPortRange]",
"sourceAddressPrefix": "[parameters('vNetProperties').networkSecurityGroups[copyIndex('NSGs')].securityRules[copyIndex('securityRules')].sourceAddressPrefix]",
"destinationAddressPrefix": "[parameters('vNetProperties').networkSecurityGroups[copyIndex('NSGs')].securityRules[copyIndex('securityRules')].destinationAddressPrefix]",
"access": "[parameters('vNetProperties').networkSecurityGroups[copyIndex('NSGs')].securityRules[copyIndex('securityRules')].access]",
"direction": "[parameters('vNetProperties').networkSecurityGroups[copyIndex('NSGs')].securityRules[copyIndex('securityRules')].direction]"
}
}
]
}
}
My code right now most definitely does not work. I'm at the point where I need to validate this type of logic is even possible in the ARM at this time. Is it possible to have an array, where each item in the array is an array itself, and reference both levels of arrays in such fashion as array1[i].array2[j].name?