Theoretical Foundation: Configure Management Groups
1. Initial Intuitionβ
Imagine a multinational company with subsidiaries in several countries. Each subsidiary has its own operations, its own teams, and its own projects. The headquarters needs to ensure that certain corporate policies are followed by everyone: tax compliance, security standards, regulatory restrictions by country. Doing this subsidiary by subsidiary would be unfeasible at scale.
In Azure, when you have multiple subscriptions, the problem is exactly the same: how to apply governance at scale across dozens or hundreds of subscriptions without having to configure RBAC, Policies, and Locks individually in each one?
The answer is the Management Group: a container that groups subscriptions (and other Management Groups) in a hierarchy, allowing you to apply governance once at the appropriate level with automatic inheritance to everything below.
A Management Group with an assigned Policy propagates that Policy to all subscriptions within it, which propagate to all Resource Groups, which propagate to all resources. One action, impact on thousands of resources.
2. Contextβ
Where Management Groups fit in the Azure hierarchyβ
This structure is the Azure Landing Zone, Microsoft's reference architecture for enterprise organizations. Each level of the hierarchy has a specific purpose.
Why Management Groups existβ
Before Management Groups, each subscription was an isolated governance island. To apply the same 50 security policies across 20 subscriptions, you needed to create 1,000 individual policy assignments. Any change required 20 updates. Any new subscription started without governance until manually configured.
Management Groups solve this problem: a single Policy or RBAC assignment at the Management Group automatically covers all subscriptions below, present and future. New subscriptions added to the MG inherit all governance immediately.
What depends on Management Groupsβ
- Corporate governance at scale (Azure Policy at MG level)
- Centralized RBAC for multiple subscriptions
- Consolidated cost reports via Cost Management
- Microsoft Defender for Cloud compliance reports at scale
- The Azure Landing Zone pattern itself is based on Management Groups
3. Concept Constructionβ
3.1 The Tenant Root Groupβ
When an Azure AD Tenant is created, Azure automatically creates a Tenant Root Group (also called Root Management Group). This is the root Management Group of the hierarchy, the ancestor of all other Management Groups and subscriptions.
Tenant Root Group characteristics:
| Characteristic | Detail |
|---|---|
| Default name | Tenant Root Group |
| ID | Same as Azure AD Tenant ID |
| Can be renamed | Yes |
| Can be deleted | No |
| Parent | None (it's the root) |
| Who has access by default | Global Administrator (with elevation) |
The Tenant Root Group is special because any Policy or RBAC assigned here affects absolutely all resources in the tenant. For this reason, assigning anything at the Root Group should be done with extreme caution and careful review.
3.2 Who can manage the Root Groupβ
By default, nobody has access to the Tenant Root Group when creating the tenant, not even the Global Administrator of Azure AD. To have access to the Root Group, the Global Administrator must first elevate their own access:
- In Azure AD > Properties
- Enable "Access management for Azure resources"
- This grants the Global Administrator the User Access Administrator role on the Root Group
- From there, they can manage the Root Group and delegate access to others
This elevation is intentional: it protects the Root Group from accidental access and requires a conscious action to access it.
3.3 Management Group structureβ
Structural rules:
- A Management Group can have as children: other Management Groups and Subscriptions
- A Management Group (except Root) has exactly one parent
- A Subscription can belong to only one Management Group at a time
- Maximum hierarchy depth is 6 levels below the Root Group (Root doesn't count)
- A tenant can have a maximum of 10,000 Management Groups
3.4 Governance inheritanceβ
Inheritance is the central mechanism of Management Groups. It works exactly like RBAC and Policy inheritance in smaller scopes, but at scale:
The "Allowed regions Brazil" Policy assigned at the Root Group applies to Sub1 and Sub2 (and all other subscriptions in the tenant) without any additional action.
3.5 Moving subscriptions between Management Groupsβ
A subscription can be moved from one Management Group to another. At the moment of movement:
- Policies and role assignments from the source MG stop applying immediately
- Policies and role assignments from the destination MG start applying immediately
- Resources within the subscription are not technically affected
- Resources may temporarily become non-compliant if policies from the new MG are more restrictive
4. Structural Viewβ
Azure Landing Zone pattern in detailβ
Microsoft's reference pattern organizes Management Groups in layers with specific purposes:
Why the Decommissioned MG? When a subscription needs to be decommissioned, moving it to this MG automatically applies policies that block new resources and restrict access. This standardizes the subscription offboarding process.
Typical policies by hierarchy levelβ
| Level | Policy Examples | Rationale |
|---|---|---|
| Root | Allowed regions, security baseline, mandatory logging | Applies to entire organization without exception |
| Platform | Specific network configurations, advanced monitoring | Only shared infrastructure |
| Landing Zones | Mandatory tags, backup policies | All applications |
| Corp | Private endpoints, mandatory VNet integration | Apps with corporate connectivity |
| Online | Mandatory WAF, TLS certificates | Internet-facing apps |
| Sandbox | Limited SKUs, no confidential data | Controlled experimentation |
5. Practical Functioningβ
Creating and configuring a Management Groupβ
The Management Group configuration process follows a logical order:
Non-obvious behaviorsβ
Management Groups have no direct costs. Creating a Management Group doesn't generate charges. The cost is only from resources within subscriptions. MGs are management objects without financial overhead.
Renaming a Management Group doesn't change its ID. The name (displayName) is editable. The ID (used in scripts, policies, API calls) is defined at creation and immutable. Always use the ID in automation, never the name.
Deleting a Management Group removes only the container, not the subscriptions. If you delete an MG containing subscriptions, Azure doesn't delete the subscriptions. They are moved to the parent MG. But an MG with subscriptions cannot be deleted directly: first you need to move or remove all child subscriptions and MGs.
Policies at the Root Group affect even Microsoft platform subscriptions. Some internal Microsoft subscriptions for Azure management are visible in the Root Group of some tenants. Very restrictive policies at the Root Group can affect these subscriptions. Therefore, check impact at the Root Group before applying any Deny.
A subscription without explicit MG goes to the Root Group. When creating a new subscription (especially in PAYG or dev accounts), it's automatically placed in the Tenant Root Group if there's no vending process to place it in the correct MG. This means it inherits policies from the Root Group but doesn't inherit more specific policies from application MGs.
6. Implementation Methodsβ
Azure Portalβ
When to use: initial hierarchy configuration, point subscription movements, structure visualization
Access Management Groups:
- Portal > Management Groups (search or in All services menu)
- View current hierarchy
- Click on an MG to see details, subscriptions, and policies
Create a Management Group:
- Portal > Management Groups > + Create
- Define Management Group ID (alphanumeric, hyphens, underscores, max 90 characters)
- Define Display Name (readable name, editable later)
- Select parent (Root or another existing MG)
- Submit
Move subscription to a Management Group:
- Portal > Management Groups > select destination MG
- Subscriptions tab > + Add
- Select subscription
- Confirm
Or via the subscription itself:
- Portal > Subscriptions > select subscription
- Change management group
- Select destination MG
Limitation: not reproducible, no version control, slow for complex structures.
Azure CLIβ
# Elevate access to Root Group (done in portal, not via CLI directly)
# But check if access was elevated:
az role assignment list \
--scope "/" \
--query "[?roleDefinitionName=='User Access Administrator']" \
--output table
# Create Management Group
az account management-group create \
--name "mg-landing-zones" \
--display-name "Landing Zones"
# Create child MG of another MG
az account management-group create \
--name "mg-corp" \
--display-name "Corporate" \
--parent "mg-landing-zones"
# List all Management Groups
az account management-group list --output table
# View complete hierarchy (recursive)
az account management-group show \
--name "mg-landing-zones" \
--expand \
--recurse \
--output json
# Move subscription to a Management Group
az account management-group subscription add \
--name "mg-corp" \
--subscription "<sub-id>"
# Remove subscription from a Management Group
# (subscription goes to parent MG)
az account management-group subscription remove \
--name "mg-corp" \
--subscription "<sub-id>"
# Move Management Group to another parent
az account management-group update \
--name "mg-corp" \
--parent-id "mg-landing-zones-v2"
# Rename a Management Group (displayName only)
az account management-group update \
--name "mg-corp" \
--display-name "Corporate - Americas"
# Delete Management Group (must be empty)
az account management-group delete --name "mg-temp"
# Assign Policy to a Management Group
az policy assignment create \
--name "regioes-permitidas-brasil" \
--display-name "Only Brazilian regions" \
--policy "e56962a6-4747-49cd-b67b-bf8b01975c4c" \
--scope "/providers/Microsoft.Management/managementGroups/mg-landing-zones" \
--params '{"listOfAllowedLocations": {"value": ["brazilsouth", "brazilsoutheast"]}}'
# Assign RBAC to Management Group
az role assignment create \
--assignee "audit-group@company.com" \
--role "Reader" \
--scope "/providers/Microsoft.Management/managementGroups/mg-landing-zones"
# List policies assigned to an MG
az policy assignment list \
--scope "/providers/Microsoft.Management/managementGroups/mg-landing-zones" \
--output table
# List role assignments on an MG
az role assignment list \
--scope "/providers/Microsoft.Management/managementGroups/mg-landing-zones" \
--output table
Azure PowerShellβ
# Create Management Group
New-AzManagementGroup `
-GroupId "mg-landing-zones" `
-DisplayName "Landing Zones"
# Create child MG
New-AzManagementGroup `
-GroupId "mg-corp" `
-DisplayName "Corporate" `
-ParentId "/providers/Microsoft.Management/managementGroups/mg-landing-zones"
# List Management Groups
Get-AzManagementGroup | Select-Object Name, DisplayName, ParentId
# Move subscription to MG
New-AzManagementGroupSubscription `
-GroupId "mg-corp" `
-SubscriptionId "<sub-id>"
# View recursive hierarchy
Get-AzManagementGroup `
-GroupId "mg-landing-zones" `
-Expand `
-Recurse
# Assign Policy to MG
$policyDef = Get-AzPolicyDefinition -Name "e56962a6-4747-49cd-b67b-bf8b01975c4c"
New-AzPolicyAssignment `
-Name "regioes-brasil" `
-DisplayName "Only Brazilian regions" `
-Scope "/providers/Microsoft.Management/managementGroups/mg-landing-zones" `
-PolicyDefinition $policyDef `
-PolicyParameterObject @{
listOfAllowedLocations = @{
value = @("brazilsouth", "brazilsoutheast")
}
}
# Assign RBAC to MG
New-AzRoleAssignment `
-ObjectId "<group-object-id>" `
-RoleDefinitionName "Reader" `
-Scope "/providers/Microsoft.Management/managementGroups/mg-landing-zones"
# Remove subscription from MG
Remove-AzManagementGroupSubscription `
-GroupId "mg-corp" `
-SubscriptionId "<sub-id>"
# Delete empty MG
Remove-AzManagementGroup -GroupId "mg-temp"
Bicep for Management Groups as codeβ
Since Management Groups exist above the Subscription level, deployment requires targetScope = 'tenant':
// file: management-groups.bicep
targetScope = 'tenant'
// Landing Zones root MG
resource mgLandingZones 'Microsoft.Management/managementGroups@2021-04-01' = {
name: 'mg-landing-zones'
properties: {
displayName: 'Landing Zones'
}
}
// Child MG: Corporate
resource mgCorp 'Microsoft.Management/managementGroups@2021-04-01' = {
name: 'mg-corp'
properties: {
displayName: 'Corporate'
details: {
parent: {
id: mgLandingZones.id
}
}
}
}
// Child MG: Online
resource mgOnline 'Microsoft.Management/managementGroups@2021-04-01' = {
name: 'mg-online'
properties: {
displayName: 'Online'
details: {
parent: {
id: mgLandingZones.id
}
}
}
}
// Associate subscription to Corporate MG
resource subAssociation 'Microsoft.Management/managementGroups/subscriptions@2021-04-01' = {
parent: mgCorp
name: '<subscription-id>'
}
For tenant level template deployment:
az deployment tenant create \
--location "brazilsouth" \
--template-file "management-groups.bicep"
Terraformβ
# Main Management Group
resource "azurerm_management_group" "landing_zones" {
display_name = "Landing Zones"
name = "mg-landing-zones"
# parent_management_group_id omitted = child of Root Group
}
# Child MG
resource "azurerm_management_group" "corp" {
display_name = "Corporate"
name = "mg-corp"
parent_management_group_id = azurerm_management_group.landing_zones.id
}
resource "azurerm_management_group" "online" {
display_name = "Online"
name = "mg-online"
parent_management_group_id = azurerm_management_group.landing_zones.id
}
# Associate subscription to an MG
resource "azurerm_management_group_subscription_association" "prod" {
management_group_id = azurerm_management_group.corp.id
subscription_id = "/subscriptions/<sub-id>"
}
# Policy assignment on MG
resource "azurerm_management_group_policy_assignment" "allowed_regions" {
name = "allowed-regions-brazil"
management_group_id = azurerm_management_group.landing_zones.id
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c"
display_name = "Only Brazilian regions"
parameters = jsonencode({
listOfAllowedLocations = {
value = ["brazilsouth", "brazilsoutheast"]
}
})
}
# RBAC on MG
resource "azurerm_role_assignment" "reader_audit" {
scope = azurerm_management_group.landing_zones.id
role_definition_name = "Reader"
principal_id = "<group-object-id>"
}
7. Control and Securityβ
Who can manage Management Groupsβ
| Action | Required Permission |
|---|---|
| Create child MG | Management Group Contributor on parent MG, or Owner |
| Move subscription to MG | Management Group Contributor on destination MG + Owner on subscription |
| Delete MG | Management Group Contributor on MG (and MG must be empty) |
| Assign Policy on MG | Resource Policy Contributor on MG scope |
| Assign RBAC on MG | Owner or User Access Administrator on MG |
| Access Root Group | User Access Administrator on Root (via Global Admin elevation) |
Built-in roles specific for Management Groupsβ
| Role | Description |
|---|---|
| Management Group Contributor | Creates, moves and deletes Management Groups; doesn't assign roles |
| Management Group Reader | Views hierarchy and configurations; no modifications |
These roles exist specifically to delegate management of MG structure without granting Owner or Contributor on resources.
Protection against unauthorized hierarchy changesβ
Configure an Activity Log Alert to detect changes in the Management Groups hierarchy:
az monitor activity-log alert create \
--name "Alert-MG-Modified" \
--resource-group "rg-monitoring" \
--condition \
category=Administrative \
operationName=Microsoft.Management/managementGroups/write \
--scope "/" \
--action-group "/subscriptions/<sub-id>/resourceGroups/rg-monitoring/providers/microsoft.insights/actionGroups/ag-critical-alerts"
Any creation, renaming or movement of Management Groups will generate an immediate alert.
8. Decision Makingβ
When to create a Management Group vs. using only Resource Groupsβ
| Situation | Solution | Reason |
|---|---|---|
| Organization with 1-3 subscriptions | Resource Groups + Policy per subscription | MG overhead isn't justified |
| 4+ subscriptions with common governance | Management Groups | One assignment covers multiple subscriptions |
| Different compliance requirements per division | MGs per business division | Policy isolation per division |
| Prod/dev environments with different governance | MGs per environment type | Different policies, isolated inheritance |
| New subscriptions frequently created | MGs mandatory | Automatic governance for new subs |
Hierarchy design: depth vs. widthβ
| Approach | Advantages | Disadvantages |
|---|---|---|
| Shallow hierarchy (2-3 levels) | Simple to understand, easy to manage | Less granularity for specific policies |
| Deep hierarchy (5-6 levels) | Very high granularity | Difficult to debug inheritance, operational complexity |
| Balanced hierarchy (3-4 levels, recommended) | Adequate granularity without excessive complexity | Requires careful initial planning |
Number of Management Groupsβ
| Scenario | Recommendation |
|---|---|
| Startup or SME | 0 MGs (only Root + subscriptions) |
| Medium company | 4-8 MGs (Platform, Landing Zones, Sandbox + 1-2 children) |
| Enterprise | 10-30 MGs following Azure Landing Zone pattern |
| Multinational conglomerate | 30-100 MGs with hierarchy by region and division |
9. Best Practicesβ
Plan the hierarchy before implementing. Changes to MG hierarchy have immediate impact on governance of all affected subscriptions. Redesigning the hierarchy after 50 subscriptions are already positioned is laborious and risky. Define the structure on paper, validate with stakeholders and implement via IaC.
Use IaC (Bicep/Terraform) to create and manage Management Groups. Management Groups are part of organizational infrastructure and should be versioned as code. This ensures reproducibility, change auditing and review process before applying changes.
Never assign Deny policies on Root Group without extensive testing. A Deny Policy on Root Group affects 100% of tenant resources, including platform subscriptions and any subscription created in the future. Always test on a child MG before promoting to Root.
Keep Root Group with only truly universal policies. The Root Group should have only what applies to the entire organization without exception: regions allowed by regulation, mandatory minimum logging, tenant identification tags. Everything else goes to specific MGs.
Create a Sandbox MG with permissive policies for experimentation. Developers need freedom to experiment. A Sandbox MG with relaxed policies (no region Deny, no strict tag requirements, but with expensive SKU limits) enables innovation without production risk.
Create a Decommissioned MG for subscription offboarding. Subscriptions that need to be decommissioned should be moved to an MG with policies that block new resources and restrict access. This standardizes the process and prevents forgotten subscriptions from accumulating costs.
Document each Management Group with purpose, owner and restrictions. A Management Group without documentation of why it exists, who's responsible and what restrictions it imposes becomes an operational mystery. Use MG description and a design document to record this information.
Use Azure AD groups for RBAC on Management Groups. Role assignments on MGs should be made to groups, not individual users. When someone enters or leaves the company, just update the group.
10. Common Errorsβ
| Error | Why it happens | How to avoid |
|---|---|---|
| Assign Deny policy on Root Group without testing | Urgency, lack of process | Always test on child MG with only one test subscription |
| Not defining hierarchy before creating subscriptions | Starting fast without planning | Define MG structure as prerequisite for any new subscription |
| Creating too many hierarchy levels | Trying to map organizational structure 1:1 | Limit to 3-4 levels; MGs are for governance, not org chart |
| Using MG name in scripts instead of ID | Name is more readable | ID is immutable; name can change |
| Not monitoring subscription movements between MGs | Believing it rarely happens accidentally | Activity Log Alert for Management Group operations |
| Forgetting that new subscription goes to Root | Lack of vending process | Automate placement of new subscriptions in correct MG |
| Deleting parent MG without moving child subscriptions | Not knowing it's blocked | Azure blocks it; but knowing this avoids surprises |
| Applying too permissive RBAC on Root Group | Convenience | Use least privilege; Root Group inherits to everything |
The most impactful errorβ
Assigning a Deny Policy on Tenant Root Group with a misconfigured condition. For example, a Policy that denies resources without a specific tag, but the tag is case-sensitive and half the resources use "Environment" and half use "environment". Result: deployments fail across the entire organization until the Policy is fixed or removed.
11. Operation and Maintenanceβ
Hierarchy auditingβ
# View complete tenant hierarchy
az account management-group list \
--query "[].{Name:name, Display:displayName, Parent:properties.parent.name}" \
--output table
# View all subscriptions and which MG they're in
az account management-group entities list \
--query "[?type=='Microsoft.Management/managementGroups/subscriptions'].{Name:displayName, ID:name, Parent:parent.displayName}" \
--output table
# Check policies assigned on all MGs
for mg_id in $(az account management-group list --query "[].name" -o tsv); do
echo "=== MG: $mg_id ==="
az policy assignment list \
--scope "/providers/Microsoft.Management/managementGroups/$mg_id" \
--query "[].{Name:displayName, Policy:policyDefinitionId}" \
--output table
done
# Check RBAC assigned on all MGs
az role assignment list \
--scope "/providers/Microsoft.Management/managementGroups/mg-landing-zones" \
--include-inherited \
--output table
Monitor hierarchy changesβ
# View Management Group change history
az monitor activity-log list \
--resource-provider "Microsoft.Management" \
--query "[?operationName.value=='Microsoft.Management/managementGroups/write' || operationName.value=='Microsoft.Management/managementGroups/subscriptions/write']" \
--output table
Important Management Group limitsβ
| Limit | Value |
|---|---|
| Management Groups per tenant | 10,000 |
| Depth levels (excluding Root) | 6 |
| Subscriptions per Management Group | No documented limit |
| Direct children of a Management Group | No documented limit |
| Role assignments per Management Group | 500 |
| Policy assignments per Management Group | 500 |
The limit of 500 role assignments per Management Group is separate from the 4,000 per subscription limit. Assignments on MG consume from the MG limit, not the subscriptions below.
12. Integration and Automationβ
Subscription Vending with automatic MG placementβ
Azure Landing Zone Acceleratorβ
Microsoft provides the Azure Landing Zone as ready-to-use code:
# Clone Azure Landing Zone repository (Terraform)
git clone https://github.com/Azure/terraform-azurerm-caf-enterprise-scale
# Configure main variables
cat > terraform.tfvars << EOF
root_id = "company"
root_name = "Company Corp"
root_parent_id = "tenant-root-group-id"
EOF
# Full deployment of MG hierarchy
terraform init
terraform plan
terraform apply
This creates the entire Management Groups hierarchy (Platform, Landing Zones, Sandbox, Decommissioned and their children), with baseline policies and role assignments already configured.
Integration with Microsoft Defender for Cloudβ
Defender for Cloud aggregates security scores by Management Group, giving a consolidated view of security posture for all subscriptions:
# View aggregated secure score by Management Group
az security secure-score list \
--query "[].{Name:displayName, Score:currentScore.current, Max:currentScore.max, Percent:currentScore.percentage}" \
--output table
With well-configured Management Groups, you can see "Production MG has Secure Score of 78%" versus "Development MG has 45%", allowing you to prioritize security investments where they matter most.
13. Final Summaryβ
Essential points:
- Management Groups are containers that group subscriptions (and other MGs) in a governance hierarchy
- The Tenant Root Group is automatically created for each tenant and is the ancestor of the entire hierarchy
- Inheritance is the central mechanism: Policy and RBAC assigned on an MG apply to all subscriptions and resources below
- Maximum hierarchy depth is 6 levels below the Root Group
- Maximum limit is 10,000 Management Groups per tenant
- To access the Root Group, a Global Administrator needs to elevate their access explicitly
Critical differences:
- MG vs. Subscription: MG is governance container with no direct cost; Subscription is billing and resource unit
- MG vs. Resource Group: MG groups subscriptions; RG groups resources within a subscription
- MG ID vs. DisplayName: ID is immutable (use in scripts); DisplayName is editable (human-readable name)
- Role assignment limit on MG (500) vs. Subscription (4,000): separate and independent counters
What needs to be remembered for AZ-104:
- Every tenant has a Tenant Root Group automatically created with the same ID as the tenant
- The Root Group cannot be deleted
- A subscription belongs to exactly one MG at a time; can be moved between MGs
- The scope string of an MG is:
/providers/Microsoft.Management/managementGroups/{managementGroupId} - To create a deployment that creates MGs, the
targetScopemust betenantin Bicep and the command isaz deployment tenant create - When a subscription is moved from MG, the policies and RBAC from the source MG are removed immediately and those from the destination are applied immediately
- New subscriptions without explicit placement automatically go to the Tenant Root Group
- The limit of 500 role assignments per MG is different and independent from the 4,000 per subscription limit