How to define specific Resource Group in Azure Resource Manager nested template
Asked Answered
B

2

5

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?

Barquentine answered 11/2, 2016 at 10:50 Comment(3)
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.Outcaste
That's what I'm beginning to think tooBarquentine
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.Glavin
E
8

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://learn.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": {
            }
        }
    ]
}
Estellaestelle answered 18/1, 2018 at 10:10 Comment(6)
This is very helpful. Will this also create the resource group if it doesn't exist ?Lumberyard
@vicky I think it won't create the resource group, but not 100% sure. The MS Powershell scripts create the RG before triggering a deployment on it, which tells me it probably won't create itEstellaestelle
It will not automatically create the Resource Group in the nested Template. learn.microsoft.com/en-us/azure/azure-resource-manager/…Jolda
I also do not believe nesting a Subscription-level template is supported, unfortunately. (ie: Using "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#" )Jolda
How do you define dependencies to a nested template? Lets say I have a Function App that I define in ARM in the main template, and this Function App needs VNET integration. The VNET itself is defined in the nested template.Jovita
@oliver Nielsen you would have to swap it around. The VNet can be in the outer template, and the function app deployed in the sub template. You can then use the dependsOn property on the sub deployment to make ARM only run the inner function app deployment once the outer one is complete. You can also look into Hashicorp Terraform, it works well for complex deployment scenariosEstellaestelle
T
5

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.

Torchwood answered 12/2, 2016 at 4:35 Comment(2)
I agree - that was both my understanding but I was hoping I was wrong, especially when their own documentation advises using Resource Groups to store items of matching lifecycle and/or management requirements. In my example, I'm aiming to have admin items in one RG, then Prod, UAT, Dev etc. in their own separate ones too (plus Key Vault on its own). I'm beginning to realise that I'll have to do this by calling my templates iteratively from PowerShell - not ideal, but not impossible either.Barquentine
My deployment process has always included an initial powershell script that pre-flight stuff prior to running templates. and then running a number of templates to create the solution that is required.Torchwood

© 2022 - 2024 — McMap. All rights reserved.