Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
With Azure Resource Manager templates (ARM templates), you can deploy to resource groups, subscriptions, management groups, or tenants. Generally, ARM template functions work the same for all scopes. This article describes the differences that exist for some functions and how these differences depend on the scope.
Supported functions
Consider the following when deploying to different scopes:
The
resourceGroup()
function is supported for resource group deployments.The
subscription()
function is supported for resource-group and subscription deployments.The
reference()
and list() functions are supported for all scopes.Use
resourceId()
to get the ID for a resource deployed at the resources group."subnet": { "id": "[resourceId(parameters('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnet1Name'))]" }
Use the
subscriptionResourceId()
function to get the ID for a resource deployed at the subscription.For example, to get the resource ID for a policy definition that's deployed to a subscription, use:
"roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]"
Use the
extensionResourceId()
function for resources that implement as extensions of the management group. Custom policy definitions that are deployed to the management group are extensions of the management group.To get the resource ID for a custom policy definition at the management-group level, use:
"policyDefinitionId": "[extensionResourceId(variables('mgScope'), 'Microsoft.Authorization/policyDefinitions', parameters('policyDefinitionID'))]"
Use the
tenantResourceId()
function to get the ID for a resource deployed at the tenant. Built-in policy definitions are tenant-level resources. When assigning a built-in policy at the management-group level, use thetenantResourceId
function.To get the resource ID for a built-in policy definition, use:
"policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policyDefinitions', parameters('policyDefinitionID'))]"
Function resolution in scopes
When you deploy to more than one scope, the resourceGroup()
and subscription()
functions resolve differently based on how you specify the template. When you link to an external template, the functions always resolve to the scope for that template. When you nest a template within a parent template, use the expressionEvaluationOptions
property to specify if the functions resolve to the resource group and subscription for the parent template or the nested template. Set the property to inner
to resolve to the scope for the nested template. Set the property to outer
to resolve to the scope of the parent template.
The following table shows if the functions resolve to the parent or embedded resource group and subscription.
Template type | Scope | Resolution |
---|---|---|
nested | outer (default) | Parent resource group |
nested | inner | Sub resource group |
linked | N/A | Sub resource group |
The following example template shows a:
- Nested template with a default (
outer
) scope. - Nested template with an
inner
scope. - Linked template.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "defaultScopeTemplate",
"resourceGroup": "inlineGroup",
"properties": {
"mode": "Incremental",
"parameters": {},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [],
"outputs": {
"resourceGroupOutput": {
"type": "string",
"value": "[resourceGroup().name]"
}
}
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "innerScopeTemplate",
"resourceGroup": "inlineGroup",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [],
"outputs": {
"resourceGroupOutput": {
"type": "string",
"value": "[resourceGroup().name]"
}
}
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"name": "linkedTemplate",
"resourceGroup": "linkedGroup",
"properties": {
"mode": "Incremental",
"parameters": {},
"templateLink": {
"contentVersion": "1.0.0.0",
"uri": "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/resourcegroupname.json"
}
}
}
],
"outputs": {
"parentRG": {
"type": "string",
"value": "[format('Parent resource group is {0}', resourceGroup().name)]"
},
"defaultScopeRG": {
"type": "string",
"value": "[format('Default scope resource group is {0}', reference('defaultScopeTemplate').outputs.resourceGroupOutput.value)]"
},
"innerScopeRG": {
"type": "string",
"value": "[format('Inner scope resource group is {0}', reference('innerScopeTemplate').outputs.resourceGroupOutput.value)]"
},
"linkedRG": {
"type": "string",
"value": "[format('Linked resource group is {0}', reference('linkedTemplate').outputs.resourceGroupOutput.value)]"
}
}
}
To test the preceding template and see the results, use PowerShell or the Azure CLI.
New-AzResourceGroup -Name parentGroup -Location southcentralus
New-AzResourceGroup -Name inlineGroup -Location southcentralus
New-AzResourceGroup -Name linkedGroup -Location southcentralus
New-AzResourceGroupDeployment `
-ResourceGroupName parentGroup `
-TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/crossresourcegroupproperties.json
The output from the preceding example is:
Name Type Value
=============== ========================= ==========
parentRG String Parent resource group is parentGroup
defaultScopeRG String Default scope resource group is parentGroup
innerScopeRG String Inner scope resource group is inlineGroup
linkedRG String Linked resource group is linkedgroup
Next steps
- To learn more about defining parameters in your template, see the structure and syntax of ARM templates.
- For tips on resolving common deployment errors, see how to troubleshoot common Azure deployment errors with Azure Resource Manager.
- For information about deploying a template that requires an SAS token, see how to deploy private ARM template with SAS token.