Azure ARM template copy function - Using Objects as parameters with multiple resource properties
30 Oct 2021 Written by Ajo MathewI was following this Azure Document to try out Azure ARM copy operation to loop through properties of an azure resource. Looks like the page was not updated correctly so I raised an issue with the MS Docs github page. This was just minor change - where NSG properties were not correctly reprsented in that example document. You can follow below correct ARM templates.
ARM template
Parameter
Using Copy to update multiple properties for a resource.
Note: I am not using full ARM templates but snippets - Assumption is that you know basics of ARM templates. My requirement was to get Azure ARM copy function to update multiple properties in an ARM template.
For example I am creating an Azure WAF/Application Gateway. The code of the resource would look like below
{
"name": "[parameters('applicationGatewayName')]",
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2019-09-01",
"location": "[parameters('location')]",
"zones": "[parameters('zones')]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
"[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIpAddressName'))]"
],
"tags": {},
"properties": {
"sku": {
"name": "[parameters('skuSize')]",
"tier": "[parameters('tier')]",
"capacity": "[parameters('capacity')]"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGwPublicFrontendIp",
"properties": {
"PublicIPAddress": {
"id": "[variables('publicIPRef')]"
}
}
},
{
"name": "appGwPrivateFrontendIp",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},
"privateIPAddress": "[parameters('privateIpAddress')]",
"privateIPAllocationMethod": "Static"
}
}
],
"frontendPorts": [
{
"name": "port_80",
"properties": {
"Port": 80
}
}
],
"backendAddressPools": [
{
"name": "dataikubackendpool",
"properties": {
"backendAddresses": [
{
"copy": [
{
"name": "subnets",
"count": 2,
"input": {
"fqdn": "parameters('backend')[copyIndex('subnets')]"
}
}
]
}
]
}
}
],
"backendHttpSettingsCollection": [
{
"name": "httpsettings",
"properties": {
"Port": 80,
"Protocol": "Http",
"cookieBasedAffinity": "Disabled",
"requestTimeout": 20
}
}
],
"httpListeners": [
{
"name": "dataikulisteneter",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(variables('applicationGatewayId'), '/frontendIPConfigurations/appGwPrivateFrontendIp')]"
},
"frontendPort": {
"id": "[concat(variables('applicationGatewayId'), '/frontendPorts/port_80')]"
},
"protocol": "Http",
"sslCertificate": null
}
}
],
"requestRoutingRules": [
{
"Name": "dataikuroutingrule",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(variables('applicationGatewayId'), '/httpListeners/this_place_holder')]"
},
"priority": null,
"backendAddressPool": {
"id": "[concat(variables('applicationGatewayId'), '/backendAddressPools/this_place_holder')]"
},
"backendHttpSettings": {
"id": "[concat(variables('applicationGatewayId'), '/backendHttpSettingsCollection/httpsettings')]"
}
}
}
],
"enableHttp2": false,
"sslCertificates": [],
"probes": []
}
}
My reqirement is to parameterize resources[0]."type : Microsoft.Network/applicationGateways".
properties frontend ports and backend http settings.
I want to pass below parameters and have Azure Copy to take care of the task - snippet from parameters.json as snow below.
"frontendPortsAvailable": {
"value": {
"frontendPorts": [
{
"name": "port_80",
"Port": 80
},
{
"name": "port_8080",
"Port": 8080
}
]
}
},
"backendHttpSettingsCollection": {
"value": {
"backendHttpSettings": [
{
"name": "http_80Settings",
"port": 80,
"Protocol": "Http",
"cookieBasedAffinity": "Disabled",
"requestTimeout": 20
},
{
"name": "http_8080Settings",
"port": 8080,
"Protocol": "Http",
"cookieBasedAffinity": "Disabled",
"requestTimeout": 20
},
{
"name": "http_8081Settings",
"port": 8081,
"Protocol": "Http",
"cookieBasedAffinity": "Disabled",
"requestTimeout": 20
}
]
}
}
I have my templates.json variables as
"frontendPortsAvailable": {
"type": "object"
},
"backendHttpSettingsCollection": {
"type": "object"
}
When I tried to use multiple copy nodes inside ARM templates my vscode has warned me this is not allowed.
"copy": [
{
"name": "frontendPorts",
"count": "[length(parameters('frontendPortsAvailable').frontendPorts)]",
"input": {
"name": "[parameters('frontendPortsAvailable').frontendPorts[copyIndex('frontendPorts')].name]",
"properties": {
"Port": "[parameters('frontendPortsAvailable').frontendPorts[copyIndex('frontendPorts')].Port]"
}
}
}],
"copy":[
{
"name": "backendHttpSettingsCollection",
"count": "[length(parameters('backendHttpSettingsCollection').backendHttpSettings)]",
"input": {
"name": "[parameters('backendHttpSettingsCollection').backendHttpSettings[copyIndex('backendHttpSettingsCollection')].name]",
"properties": {
"Port": "[parameters('backendHttpSettingsCollection').backendHttpSettings[copyIndex('backendHttpSettingsCollection')].port]",
"Protocol": "[parameters('backendHttpSettingsCollection').backendHttpSettings[copyIndex('backendHttpSettingsCollection')].Protocol]",
"cookieBasedAffinity": "[parameters('backendHttpSettingsCollection').backendHttpSettings[copyIndex('backendHttpSettingsCollection')].cookieBasedAffinity]",
"requestTimeout": "[parameters('backendHttpSettingsCollection').backendHttpSettings[copyIndex('backendHttpSettingsCollection')].requestTimeout]"
}
}
}
]
it is sooo ❤ good that VS code intelisense was able to point out mistakes The final templates and parameters looks as below.
Template Parameters