ARM Template Dependencies

If you have used ARM templates for your azure infrastructure deployments, you would have noticed that some of the resources are dependent on the presence of one or more resources. This is usually denoted using the “dependsOn” property within the resource’s definition section. This lets the Azure Resource Manager determine the order of deployment of the resources. Internally the ARM has to build a detailed resource dependency graph before executing the actual deployment.

Dependencies in Azure Virtual WAN

Azure vWan with hubs in multiple regions, multiple hybrid connections in every region and multiple azure virtual networks creates a huge deployment request by itself. Microsoft has provided a reference template for an any-to-any routing deployment. You can find that at https://github.com/Azure/azure-quickstart-templates/tree/master/quickstarts/microsoft.network/virtual-wan-with-all-gateways

With so many components deployed in a fully managed hub & spoke network model, it is usually difficult to understand the dependencies between the components. The following table has a list of all the dependencies.

NoComponentDependency
1First Spoke Virtual Network Connection in the regiona) Virtual Hub
b) The target virtual network
c) Site-to-Site VPN Gateway in that region
2Subsequent Virtual Network Connections in the regiona) Virtual Hub
b) The target virtual network
c) First Virtual Network Connection
3S2S VPN GatewaysVirtual Hub
4Express Route GatewaysThe last Hub Virtual network connection in that region
5VPN Server ConfigurationExpress Route Gateway in that region
6P2S VPN GatewaysThe corresponding VPN Server configuration

Inferences Explained

  1. The first spoke virtual network connection in the region would be dependent on the Virtual-Hub, the target virtual network and the Site to Site VPN gateway in the same region
    • The point to note here is the S2S VPN Gateway. The following code snippet shows the dependencies section. The reason why the virtual network connection is made dependent on the S2S VPN Gateway is to enable the Virtual Network connect to the On-Premise site through the VPN connection. The second code block shows the corresponding setting that makes this a required dependency
 "name": "[format('{0}/{1}_connection', variables('virtual_hub1_cfg').name, variables('vnet1_cfg').name)]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualHubs', variables('virtual_hub1_cfg').name)]",
                "[resourceId('Microsoft.Network/virtualNetworks', variables('vnet1_cfg').name)]",
                "[resourceId('Microsoft.Network/vpnGateways', format('{0}_S2SvpnGW', variables('virtual_hub1_cfg').name))]"
            ],
 "properties": {
                "remoteVirtualNetwork": {
                    "id": "[resourceId('Microsoft.Network/virtualNetworks', variables('vnet1_cfg').name)]"
                },
                "allowHubToRemoteVnetTransit": true,
                "allowRemoteVnetToUseHubVnetGateways": true,
                "enableInternetSecurity": true
            }

2. The subsequent virtual networks in the same region are made dependent on the first virtual network connection. While there might not be a direct dependency on the “hub virtual network connection”, the reason for this could be indirect dependency on the VPN Gateway

"name": "[format('{0}/{1}_connection', variables('virtual_hub1_cfg').name, variables('vnet2_cfg').name)]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualHubs', variables('virtual_hub1_cfg').name)]",
                "[resourceId('Microsoft.Network/virtualNetworks', variables('vnet2_cfg').name)]",
                "[resourceId('Microsoft.Network/virtualHubs/hubVirtualNetworkConnections', variables('virtual_hub1_cfg').name, format('{0}_connection', variables('vnet1_cfg').name))]"
            ],

3. The S2S VPN Gateway has a dependency on the regional hub. This is because the virtual hub is actually an Azure Managed Virtual Network that is to be visualized as the Hub in a Hub & Spoke Topology. The Gateways including the S2S VPN gateway get deployed to the hub network.

"name": "[format('{0}_S2SvpnGW', variables('virtual_hub1_cfg').name)]",
            "apiVersion": "2020-05-01",
            "location": "[parameters('hub1_location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualHubs', variables('virtual_hub1_cfg').name)]"
            ],

4. The Express Route Gateways are made dependent on the last of all hub virtual network connections in the same region. There is no direct explanation for this in the Microsoft documentation.

"name": "[format('{0}_ERGW', variables('virtual_hub1_cfg').name)]",
            "location": "[parameters('hub1_location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualHubs/hubVirtualNetworkConnections', variables('virtual_hub1_cfg').name, format('{0}_connection', variables('vnet2_cfg').name))]"
            ],

5. The VPN Sever configuration is made dependent on the Express Route Gateway. There is no possible explanation that I could think of. However this dependency needs to be coded as is for the deployment to go through. This is a necessity in a topology that has all the 3 hybrid connection gateways

 "name": "[format('{0}_P2SvpnServerConfiguration', variables('virtual_hub1_cfg').name)]",
            "location": "[parameters('hub1_location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/expressRouteGateways', format('{0}_ERGW', variables('virtual_hub1_cfg').name))]"
            ],

6. The P2S VPN Gateways are made dependent on the corresponding VPN server configurations. This is self-explanatory.

"name": "[format('{0}_P2Sgateway', variables('virtual_hub1_cfg').name)]",
            "location": "[parameters('hub1_location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/vpnServerConfigurations', format('{0}_P2SvpnServerConfiguration', variables('virtual_hub1_cfg').name))]"
            ],

Queries posted to MS

I modified the base deployment template and played around a bit

  1. Have only the express route gateway in a region and make that as the dependency of the hub virtual network connections (points #1 and #2)
  2. Have only the S2S and P2S VPN gateways in a region. This was the obvious design choice to skip deploying the express route gateway in a region that you do not have a ER Circuit to connect to. So I removed the dependency of the P2S Gw on the ER Gateway. To my surprise, the deployment failed with a conflict error during the deployment of the P2S VPN Gateway. To workaround this issue I had to deploy an ER Gw even if it is not connecting to a circuit.

I created a support ticket to get MS help me understand the issue and the way to fix it. The main reason is not everyone would need an express route connection in every region that they deploy the virtual wans to. Unfortunately, MS folks were not able to help me. I managed to complete the deployment with whatever workaround that I had stated in point#2