Nested ARM template and dependsOn in another Resource Group

2.1k views Asked by At

I am trying to create a Function App with VNET Integration in ARM. I have made all that work just fine in one main template.

Now I have a new requirement where the VNET needs to be in another RG and thus seperate from the Func App RG, but the Func App still needs to have VNET integration to the VNET in the other RG.

I'm struggling how to define the ARM template, so that I deploy the Func App in one RG and VNET in another. The hard part is how to define this so that the Func App integrates into a VNET in another RG in the same ARM template using nested template.

Here is my ARM template:

"resources": [{
        "type": "Microsoft.Resources/deployments",
        "apiVersion": "2019-10-01",
        "name": "nestedTemplate",
        "resourceGroup": "[parameters('VNETPeered_RG_Name')]",
        "subscriptionId": "0a2009c0-e2ae-4991-aa0e-5c34c141e4cb",
        "properties": {
            "mode": "Incremental",
            "template": {
                "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                "contentVersion": "1.0.0.0",
                "parameters": {},
                "variables": {},
                "resources": [{
                        "comments": "Virtual Network for VNET integration feature in the Premium Plan for the Function App",
                        "type": "Microsoft.Network/virtualNetworks",
                        "apiVersion": "2019-11-01",
                        "name": "[variables('virtual_network_name')]",
                        "location": "[resourceGroup().location]",
                        "properties": {
                            "addressSpace": {
                                "addressPrefixes": [
                                    "[parameters('vnetAddressPrefix')]"
                                ]
                            },
                            "subnets": [{
                                    "name": "[variables('subnet_name')]",
                                    "properties": {
                                        "addressPrefix": "[parameters('subnet1Prefix')]",
                                        "serviceEndpoints": [{
                                                "service": "Microsoft.Storage",
                                                "locations": [
                                                    "[resourceGroup().location]"
                                                ]
                                            }
                                        }
                                    }]
                            }
                        }]
                }
            }
        },
        {
            "comments": "Function App to host the functions themselves. Integrates into a VNET and makes use of Azure DNS Private Zones.",
            "type": "Microsoft.Web/sites",
            "apiVersion": "2019-08-01",
            "name": "[variables('function_app_name')]",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "nestedTemplate",
                "[resourceId('Microsoft.Storage/storageAccounts', variables('storage_account_name'))]",
                "[resourceId('Microsoft.Web/serverfarms', variables('app_service_plan_name'))]"
            ],
            "kind": "functionapp",
            "identity": {
                "type": "SystemAssigned"
            },
            "properties": {
                "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('app_service_plan_name'))]",
                "siteConfig": {
                    "appSettings": [{
                        "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
                        "value": "[reference(variables('application_insights_resourceId'), '2018-05-01-preview').InstrumentationKey]"
                    }]
                },
                "clientAffinityEnabled": true
            },
            "resources": [{
                "type": "networkConfig",
                "apiVersion": "2019-08-01",
                "name": "virtualNetwork",
                "dependsOn": [
                    "[resourceId('Microsoft.Web/sites', variables('function_app_name'))]"
                ],
                "properties": {
                    "subnetResourceId": "[reference(resourceId('RG-FunctionsGroup','Microsoft.Network/virtualNetworks/subnets', 'vn-MY-VNET', 'sn-MY-SUBNET'),'2020-05-01')]",
                    "isSwift": true
                }
            }]
        ]
    }

On this I get the following error when I try to deploy it with az deployment group command from az cli:

Deployment failed. Correlation ID: 39b0173b-8a51-42c5-a796-1d3427556194. {
  "error": {
    "code": "InternalServerError",
    "message": "There was an unexpected InternalServerError.  Please try again later.  x-ms-correlation-request-id: 844e9f35-2e9c-411a-817d-9045511558cb"
  }
}
2

There are 2 answers

0
Llazar On BEST ANSWER

Your problem is in this part of code:

 "properties": {
                "subnetResourceId": "[reference(resourceId('RG-FunctionsGroup','Microsoft.Network/virtualNetworks/subnets', 'vn-MY-VNET', 'sn-MY-SUBNET'),'2020-05-01')]",
                "isSwift": true
            }

You are pointing the subnet with the wrong resource group. Change the resource group where the vnet and the subnet is deployed.

 "properties": {
                "subnetResourceId": "[reference(resourceId(parameters('VNETPeered_RG_Name'),'Microsoft.Network/virtualNetworks/subnets', variables('virtual_network_name'), variables('subnet_name')),'2020-05-01')]",
                "isSwift": true
            }
0
bmoore-msft On

reference() will work but TLDR; it's a little heavyweight

https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource#resourceid

is all you need in this case. To "reference" any resource in ARM you'll use the resourceId - there are a handful of functions to help but it really helps if you understand the basics of the resourceId, which is summarized here:

https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource#return-value-6

When you want a resourceId to a resource in the same deployment (which is not the same as the same template) you can use the shorthand version

resourceId({namespace/resourceType}, {resourceName})

If it's in a different RG, you need to add the RG param, and if it's in a different sub you need to add that too. I can't tell for certain with your snippet, but it looks like all you need in your case is this (assuming the vnet and fn app are in the same subscription):

"subnetResourceId": "[resourceId(parameters('VNETPeered_RG_Name'), 'Microsoft.Network/virtualNetworks/subnets', variables('virtual_network_name'), variables('subnet_name'))]"

That help?