5
votes

Does anyone know how to place Resources in an ARM template into specific, and different Resource Groups? This might be the storage in one RG and the network in another, both created in the same, or different, templates (nested, for example).

Full details are below.


Reading through the best practice guide ARM template best practice and the whitepaper World Class ARM Templates Considerations and Proven Practices there's a recommendation that different elements of a deployment should be situated in separate Resource Groups. For example, in an IaaS solution, your DCs might sit in an Admin RG, your back-end servers in another, and your client desktops in a third.

I'm currently trying to deploy such a solution via nested templates, and I've stumbled upon an issue whereby all items being created are automatically placed inside the Resource Group selected when kicking the process off (i.e. the parent template). I've looked through the various documentation online but can't obviously find a way to force resources being created in a template into a specific Resource Group. Has anyone done this?

2
My understanding was that every template, including its nested templates, was for exactly one resource group. Solutions composed of multiple resource groups would require multiple templates.BenV
That's what I'm beginning to think tooAndyHerb
Another way to think about resource groups (and templates to some extent) is that they are "lifecycle" boundaries. So things with the same lifecycle go into the same RG and as a result the same template. So you likely wouldn't deploy your vnet the same time you deploy the VMs in it. All that said I'm interested to see if there's a natural way to do what you're after as Michael's answer below (and Ben's above) are correct.bmoore-msft

2 Answers

6
votes

For anyone else that finds this in google (like I did):

It is now possible to deploy resources to multiple resource groups in one ARM template. Microsoft has details available here: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-cross-resource-group-deployment for the details.

To do this you include a nested deployment template within the main one, and set the nested deployment to another resource group. here is an example from the MS Site:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storagePrefix": {
            "type": "string",
            "maxLength": 11
        },
        "secondResourceGroup": {
            "type": "string"
        },
        "secondSubscriptionID": {
            "type": "string",
            "defaultValue": ""
        },
        "secondStorageLocation": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]"
        }
    },
    "variables": {
        "firstStorageName": "[concat(parameters('storagePrefix'), uniqueString(resourceGroup().id))]",
        "secondStorageName": "[concat(parameters('storagePrefix'), uniqueString(parameters('secondSubscriptionID'), parameters('secondResourceGroup')))]"
    },
    "resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "nestedTemplate",
            "type": "Microsoft.Resources/deployments",
            "resourceGroup": "[parameters('secondResourceGroup')]",
            "subscriptionId": "[parameters('secondSubscriptionID')]",
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "parameters": {},
                    "variables": {},
                    "resources": [
                        {
                            "type": "Microsoft.Storage/storageAccounts",
                            "name": "[variables('secondStorageName')]",
                            "apiVersion": "2017-06-01",
                            "location": "[parameters('secondStorageLocation')]",
                            "sku":{
                                "name": "Standard_LRS"
                            },
                            "kind": "Storage",
                            "properties": {
                            }
                        }
                    ]
                },
                "parameters": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('firstStorageName')]",
            "apiVersion": "2017-06-01",
            "location": "[resourceGroup().location]",
            "sku":{
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {
            }
        }
    ]
}
5
votes

It is not possible to deploy resources into multiple resource groups from a template. Simply by virtue of the fact that the Azure Resource Manager REST API Reference only has a single place to specify the resource group name.

The concept of ARM templates is that you create a resource group and deploy a template into it, and thus provide a single administrative unit from which to manage those resources. This improves over the Azure Service Management model where you had to manage each resource individually.

Nested resource groups would be quite a nice feature to fulfill your need, but I've never heard of such a thing being planned for Azure.