Proposed Pull Request Change

title description ms.topic ms.custom ms.date
Use Bicep to deploy resources to management group Describes how to create a Bicep file that deploys resources at the management group scope. how-to devx-track-bicep 12/10/2025
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
Content Truncation Detected
The generated rewrite appears to be incomplete.
Original lines: -
Output lines: -
Ratio: -
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: Use Bicep to deploy resources to management group description: Describes how to create a Bicep file that deploys resources at the management group scope. ms.topic: how-to ms.custom: devx-track-bicep ms.date: 12/10/2025 --- # Management group deployments with Bicep files This article describes how to set scope with Bicep when deploying to a management group. As your organization matures, you can deploy a Bicep file to create resources at the management group level. For example, you may need to define and assign [policies](../../governance/policy/overview.md) or [Azure role-based access control (Azure RBAC)](../../role-based-access-control/overview.md) for a management group. With management group level templates, you can declaratively apply policies and assign roles at the management group level. For more information, see [Understand scope](../management/overview.md#understand-scope). ## Supported resources Not all resource types can be deployed to the management group level. This section lists which resource types are supported. For Azure Blueprints, use: * [artifacts](/azure/templates/microsoft.blueprint/blueprints/artifacts) * [blueprints](/azure/templates/microsoft.blueprint/blueprints) * [blueprintAssignments](/azure/templates/microsoft.blueprint/blueprintassignments) * [versions](/azure/templates/microsoft.blueprint/blueprints/versions) For Azure Policy, use: * [policyAssignments](/azure/templates/microsoft.authorization/policyassignments) * [policyDefinitions](/azure/templates/microsoft.authorization/policydefinitions) * [policySetDefinitions](/azure/templates/microsoft.authorization/policysetdefinitions) * [remediations](/azure/templates/microsoft.policyinsights/remediations) For access control, use: * [privateLinkAssociations](/azure/templates/microsoft.authorization/privatelinkassociations) * [roleAssignments](/azure/templates/microsoft.authorization/roleassignments) * [roleAssignmentScheduleRequests](/azure/templates/microsoft.authorization/roleassignmentschedulerequests) * [roleDefinitions](/azure/templates/microsoft.authorization/roledefinitions) * [roleEligibilityScheduleRequests](/azure/templates/microsoft.authorization/roleeligibilityschedulerequests) * [roleManagementPolicyAssignments](/azure/templates/microsoft.authorization/rolemanagementpolicyassignments) For nested templates that deploy to subscriptions or resource groups, use: * [deployments](/azure/templates/microsoft.resources/deployments) For managing your resources, use: * [diagnosticSettings](/azure/templates/microsoft.insights/diagnosticsettings) * [tags](/azure/templates/microsoft.resources/tags) Management groups are tenant-level resources. However, you can create management groups in a management group deployment by setting the scope of the new management group to the tenant. See [Management group](#management-group). ## Set scope To set the scope to management group, use: ```bicep targetScope = 'managementGroup' ``` ## Deployment commands To deploy to a management group, use the management group deployment commands. # [Azure CLI](#tab/azure-cli) For Azure CLI, use [az deployment mg create](/cli/azure/deployment/mg#az-deployment-mg-create): ```azurecli-interactive az deployment mg create \ --name demoMGDeployment \ --location WestUS \ --management-group-id myMG \ --template-uri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/management-level-deployment/azuredeploy.json" ``` # [PowerShell](#tab/azure-powershell) For Azure PowerShell, use [New-AzManagementGroupDeployment](/powershell/module/az.resources/new-azmanagementgroupdeployment). ```azurepowershell-interactive New-AzManagementGroupDeployment ` -Name demoMGDeployment ` -Location "West US" ` -ManagementGroupId "myMG" ` -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/management-level-deployment/azuredeploy.json" ``` --- For more detailed information about deployment commands and options for deploying ARM templates, see: * [Deploy resources with ARM templates and Azure CLI](deploy-cli.md) * [Deploy resources with ARM templates and Azure PowerShell](deploy-powershell.md) * [Deploy ARM templates from Cloud Shell](deploy-cloud-shell.md) ## Deployment location and name For management group level deployments, you must provide a location for the deployment. The location of the deployment is separate from the location of the resources you deploy. The deployment location specifies where to store deployment data. [Subscription](deploy-to-subscription.md) and [tenant](deploy-to-tenant.md) deployments also require a location. For [resource group](deploy-to-resource-group.md) deployments, the location of the resource group is used to store the deployment data. You can provide a name for the deployment, or use the default deployment name. The default name is the name of the template file. For example, deploying a template named _main.bicep_ creates a default deployment name of **main**. For each deployment name, the location is immutable. You can't create a deployment in one location when there's an existing deployment with the same name in a different location. For example, if you create a management group deployment with the name **deployment1** in **centralus**, you can't later create another deployment with the name **deployment1** but a location of **westus**. If you get the error code `InvalidDeploymentLocation`, either use a different name or the same location as the previous deployment for that name. ## Deployment scopes In a Bicep file, all resources declared with the [`resource`](./resource-declaration.md) keyword must be deployed at the same scope as the deployment. For a management group deployment, this means all `resource` declarations in the Bicep file must be deployed to the same management group or as a child or extension resource of a resource in the same management group as the deployment. However, this restriction doesn't apply to [`existing`](./existing-resource.md) resources. You can reference existing resources at a different scope than the deployment. To deploy resources at multiple scopes within a single deployment, use [modules](./modules.md). Deploying a module triggers a "nested deployment," allowing you to target different scopes. The user deploying the parent Bicep file must have the necessary permissions to initiate deployments at those scopes. You can deploy a Bicep module from within a management-group scope Bicep file at the following scopes: * [The same management group](#scope-to-management-group) * [Other management groups](#scope-to-management-group) * [The subscription](#scope-to-subscription) * [The resource group](#scope-to-resource-group) * [The tenant](#scope-to-tenant) ### Scope to management group To deploy resources to the target management group, add those resources with the `resource` keyword. ```bicep targetScope = 'managementGroup' // policy definition created in the management group resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2025-03-01' = { ... } ``` To target another management group, add a [module](modules.md). Use the [managementGroup function](bicep-functions-scope.md#managementgroup) to set the `scope` property. Provide the management group name. ```bicep targetScope = 'managementGroup' param otherManagementGroupName string // module deployed at management group level but in a different management group module exampleModule 'module.bicep' = { name: 'deployToDifferentMG' scope: managementGroup(otherManagementGroupName) } ``` ### Scope to subscription You can also target subscriptions within a management group. The user deploying the template must have access to the specified scope. To target a subscription within the management group, add a module. Use the [subscription function](bicep-functions-scope.md#subscription) to set the `scope` property. Provide the subscription ID. ```bicep targetScope = 'managementGroup' param subscriptionID string // module deployed to subscription in the management group module exampleModule 'module.bicep' = { name: 'deployToSub' scope: subscription(subscriptionID) } ``` ### Scope to resource group You can also target resource groups within the management group. The user deploying the template must have access to the specified scope. To target a resource group within the management group, add a module. Use the [resourceGroup function](bicep-functions-scope.md#resourcegroup) to set the `scope` property. Provide the subscription ID and resource group name. ```bicep targetScope = 'managementGroup' param subscriptionID string param resourceGroupName string // module deployed to resource group in the management group module exampleModule 'module.bicep' = { name: 'deployToRG' scope: resourceGroup(subscriptionID, resourceGroupName) } ``` ### Scope to tenant To create resources at the tenant, add a module. Use the [tenant function](bicep-functions-scope.md#tenant) to set its `scope` property. The user deploying the template must have the [required access to deploy at the tenant](deploy-to-tenant.md#required-access). ```bicep targetScope = 'managementGroup' // module deployed at tenant level module exampleModule 'module.bicep' = { name: 'deployToTenant' scope: tenant() } ``` Or, you can set the scope to `/` for some resource types, like management groups. Creating a new management group is described in the next section. ## Management group To create a management group in a management group deployment, you must set the scope to the tenant. The following example creates a new management group in the root management group. ```bicep targetScope = 'managementGroup' param mgName string = 'mg-${uniqueString(newGuid())}' resource newMG 'Microsoft.Management/managementGroups@2024-02-01-preview' = { scope: tenant() name: mgName properties: {} } output newManagementGroup string = mgName ``` The next example creates a new management group in the management group targeted for the deployment. It uses the [management group function](bicep-functions-scope.md#managementgroup). ```bicep targetScope = 'managementGroup' param mgName string = 'mg-${uniqueString(newGuid())}' resource newMG 'Microsoft.Management/managementGroups@2024-02-01-preview' = { scope: tenant() name: mgName properties: { details: { parent: { id: managementGroup().id } } } } output newManagementGroup string = mgName ``` ## Subscriptions To use an ARM template to create a new Azure subscription in a management group, see: * [Programmatically create Azure Enterprise Agreement subscriptions](../../cost-management-billing/manage/programmatically-create-subscription-enterprise-agreement.md) * [Programmatically create Azure subscriptions for a Microsoft Customer Agreement](../../cost-management-billing/manage/programmatically-create-subscription-microsoft-customer-agreement.md) * [Programmatically create Azure subscriptions for a Microsoft Partner Agreement](../../cost-management-billing/manage/programmatically-create-subscription-microsoft-partner-agreement.md) To deploy a template that moves an existing Azure subscription to a new management group, see [Move subscriptions in ARM template](../../governance/management-groups/manage.md#move-a-subscription-in-an-arm-template) ## Azure Policy Custom policy definitions that are deployed to the management group are extensions of the management group. To get the ID of a custom policy definition, use the [extensionResourceId()](./bicep-functions-resource.md#extensionresourceid) function. Built-in policy definitions are tenant level resources. To get the ID of a built-in policy definition, use the [tenantResourceId()](./bicep-functions-resource.md#tenantresourceid) function. The following example shows how to [define](../../governance/policy/concepts/definition-structure.md) a policy at the management group level, and how to assign it. ```bicep targetScope = 'managementGroup' @description('An array of the allowed locations, all other locations will be denied by the created policy.') param allowedLocations array = [ 'australiaeast' 'australiasoutheast' 'australiacentral' ] resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2025-03-01' = { name: 'locationRestriction' properties: { policyType: 'Custom' mode: 'All' parameters: {} policyRule: { if: { not: { field: 'location' in: allowedLocations } } then: { effect: 'deny' } } } } resource policyAssignment 'Microsoft.Authorization/policyAssignments@2025-03-01' = { name: 'locationAssignment' properties: { policyDefinitionId: policyDefinition.id } } ``` ## Next steps To learn about other scopes, see: * [Resource group deployments](deploy-to-resource-group.md) * [Subscription deployments](deploy-to-subscription.md) * [Tenant deployments](deploy-to-tenant.md)
Success! Branch created successfully. Create Pull Request on GitHub
Error: