Cross subscription/resource group Azure deployment using ARM template

Cross subscription/resource group Azure deployment using ARM template


Azure Resource Manager is the deployment and management service for Azure. It provides a consistent management layer that enables you to create, update, and delete resources in your Azure subscription. You can use its access control, auditing, and tagging features to secure and organize your resources after deployment.

With ARM, you can create a template (in JSON format) that defines the infrastructure and configuration of your Azure solution. By using a template, you can repeatedly deploy your solution throughout its lifecycle and have confidence your resources are deployed in a consistent state.

When deploying the template you usually specify a single subscription/resource group, but sometimes you need to create some resources in another subscription/resource group and you want to do it in one go. In the following, I will show you how to create a template for a cross subscription/resource group deployment.

You can deploy to only five resource groups in a single deployment. Typically, this limitation means you can deploy to one resource group specified for the parent template, and up to four resource groups in nested or linked deployments. However, if your parent template contains only nested or linked templates and does not itself deploy any resources, then you can include up to five resource groups in nested or linked deployments.

You have to add a resource of type: 'Microsoft.Resources/deployments'. For the 'ResourceGroup' and 'SubscriptionId' properties to work please use api-version '2017-05-10' or later to deploy the template (using the SDK for example: Microsoft.Azure.Management.ResourceManager v2.3.0-preview).

{
   "$schema":"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
   "contentVersion":"1.0.0.0",
   "parameters":{
      "secondResourceGroup":{
         "type":"string"
      },
      "secondSubscriptionId":{
         "type":"string",
         "defaultValue":""
      }
   },
   "variables":{
      "firstStorageName":"[uniqueString(parameters('secondSubscriptionId'), parameters('secondResourceGroup'))]",
      "secondStorageName":"[uniqueString(parameters('secondSubscriptionId'), parameters('secondResourceGroup'))]",
      "thirdStorageName":"[uniqueString(resourceGroup().id)]"
   },
   "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('firstStorageName')]"
                  },
                  {
                     "type":"Microsoft.Storage/storageAccounts",
                     "name":"[variables('secondStorageName')]",
                     "dependsOn":[
                        "[resourceId(parameters('secondSubscriptionId'), parameters('secondResourceGroupName'), 'Microsoft.Storage/storageAccounts', variables('firstStorageName'))]"
                     ]
                  }
               ]
            },
            "parameters":{

            }
         }
      },
      {
         "type":"Microsoft.Storage/storageAccounts",
         "name":"[variables('thirdStorageName')]",
         "dependsOn":[
            "nestedTemplate"
         ]
      }
   ]
}

This resource behaves like any other, it can be used, for example, in the 'DependsOn' property of a resource from the parent template.

Variables and parameters from the parent template can be used in the nested template.

Be very careful with:
  • always use 'Incremetal' mode for the nested template (in 'Complete' mode, ARM deletes resources that exist in the resource group but aren't specified in the template)
  • resources from the parent template are not accessible in the nested template
  • some functions resolve differently in the nested template:
    • the resourceGroup() and subscription() functions resolve to the parent resource group and subscription
    • the resourceId(...) needs the subscription and resource group parameters to be explicitly specified
    • etc.

Enjoy (ง°ل͜°)ง

Comments

Popular Posts