azureazure-resource-managerazure-private-dns-zone

Nested copy loop ARM template


Trying to create an ARM template with a double copy loop:

    {
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "privateDnsZones": {
            "type": "array",
            "metadata": {
                "description": "List of private DNS zones to create"
            },
            "allowedValues": [
                "privatelink.azure-automation.net", // Azure Automation  / Webhook,
                "and more"
            ]
        },
        "virtualNetworkName": {
            "type": "string",
            "metadata": {
                "description": "Name of the Virtual Network to attach the PrivateLink DNS Zones to."
            }
        },
        "virtualNetworkResourceGroupName": {
            "type": "string",
            "metadata": {
                "description": "Name of the Resource Group containing the Virtual Network."
            }
        }
    },
    "resources": [
        {
            "type": "Microsoft.Network/privateDnsZones",
            "name": "[parameters('privateDnsZones')[copyIndex()]]",
            "apiVersion": "2020-01-01",
            "location": "global",
            "copy": {
                "name": "zone",
                "count": "[length(parameters('privateDnsZones'))]"
            }
        },
        {
            "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
            "name": "[concat(parameters('privateDnsZones')[copyIndex('link')], '/', parameters('virtualNetworkResourceGroupName'),'-',parameters('virtualNetworkName'))]",
            "apiVersion": "2020-06-01",
            "location": "global",
            "copy": {
                "name": "link",
                "count": "[length(parameters('privateDnsZones'))]"
            },
            "dependsOn": [
                "zone"
            ],
            "properties": {
                "registrationEnabled": false,
                "virtualNetwork": {
                    "id": "[resourceId(parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
                }
            }
        }
    ]
}

So far it is going just fine. It deploys the multiple private dns zones as expected. Now I want to change the template so that I can deploy multiple zones and also link the zones to multiple vNets.

Parameter file would looks something like this:

    {
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "privateDnsZones": {
            "value": [
                "privatelink.blob.core.windows.net",
                "privatelink.table.core.windows.net"
            ]
        },
        "virtualNetwork": {
            "value": [
                {
                    "vnetName": "vnet1",
                    "resourceGroup": "vnet1",
                    "subscriptionId": "11111111-1111-1111-1111-111111111111"
                },
                {
                    "vnetName": "vnet2",
                    "resourceGroup": "vnet2",
                    "subscriptionId": "22222222-2222-2222-2222-222222222222"
                }
            ]
        }
    }
}

Idea would be that the template loops trough the Pricate DNS Zones, but also through the virtualNetworks. The tricky part for me is that I need the information of both loops in the name of the link. Tried multiple things, but ended up with or syntax error within the template or errors during deployment.

Hopefully someone can give me a push in the right direction...


Solution

  • I got it to work: Template file:

    {
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "privateDnsZones": {
            "type": "array",
            "metadata": {
                "description": "List of private DNS zones to create"
            },
            "allowedValues": [
                "privatelink.azure-automation.net", // Azure Automation  / Webhook, DSCAndHybridWorker
                "privatelink.database.windows.net", // Azure SQL Database / SQL Server / Azure Synapse Analytics
                "and many more...."
            ]
        },
        "virtualNetworks": {
            "type": "array",
            "metadata": {
                "description": "Name of the Virtual Network to attach the PrivateLink DNS Zones to."
            }
        }
    },
    "variables": {
        "NumberOfLoops": "[mul(length(parameters('privateDnsZones')),length(parameters('virtualNetworks')))]",
        "lengthPrivateDnsZones": "[length(parameters('privateDnsZones'))]",
        "lengthvirtualNetworks": "[length(parameters('virtualNetworks'))]"
    },
    "resources": [
        {
            "type": "Microsoft.Network/privateDnsZones",
            "name": "[parameters('privateDnsZones')[copyIndex()]]",
            "apiVersion": "2020-01-01",
            "location": "global",
            "copy": {
                "name": "zone",
                "count": "[length(parameters('privateDnsZones'))]"
            }
        },
        {
            "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
            "name": "[concat(parameters('privateDnsZones')[mod(copyIndex(),variables('lengthPrivateDnsZones'))], '/', parameters('virtualNetworks')[mod(div(copyIndex(),variables('lengthPrivateDnsZones')),variables('lengthvirtualNetworks'))].resourceGroup,'-',parameters('virtualNetworks')[mod(div(copyIndex(),variables('lengthPrivateDnsZones')),variables('lengthvirtualNetworks'))].vnetName)]",
            "apiVersion": "2020-06-01",
            "location": "global",
            "copy": {
                "name": "link",
                "count": "[variables('NumberOfLoops')]"
            },
            "dependsOn": [
                "zone"
            ],
            "properties": {
                "registrationEnabled": false,
                "virtualNetwork": {
                    "id": "[resourceId(parameters('virtualNetworks')[mod(div(copyIndex(),variables('lengthPrivateDnsZones')),variables('lengthvirtualNetworks'))].subscriptionId, parameters('virtualNetworks')[mod(div(copyIndex(),variables('lengthPrivateDnsZones')),variables('lengthvirtualNetworks'))].resourceGroup, 'Microsoft.Network/virtualNetworks', parameters('virtualNetworks')[mod(div(copyIndex(),variables('lengthPrivateDnsZones')),variables('lengthvirtualNetworks'))].vnetName)]"
                }
            }
        }
    ]
    

    }

    Parameter file:

    {
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "privateDnsZones": {
            "value": [
                "privatelink.azure-automation.net",
                "privatelink.database.windows.net",
                "privatelink.blob.core.windows.net",
                "privatelink.table.core.windows.net",
                "privatelink.vaultcore.azure.net",
                "privatelink.mariadb.database.azure.com",
                "privatelink.service.signalr.net"
            ]
        },
        "virtualNetworks": {
            "value": [
                {
                    "vnetName": "vnet1",
                    "resourceGroup": "vnet1",
                    "subscriptionId": "GUID"
                },
                {
                    "vnetName": "vnet2",
                    "resourceGroup": "vnet2",
                    "subscriptionId": "GUID"
                }
            ]
        }
    }
    

    }