Azure Management Groups
Compatible with the Microsoft.Management management-group API used by az account management-group,
the armmanagementgroups / azure-mgmt-managementgroups SDKs and the azurerm_management_group
Terraform resource. Models the tenant hierarchy: the tenant root group, the groups under it and the
subscriptions placed in them.
HTTP-only, no Docker. The hierarchy is in-memory and ephemeral, like the rest of the ARM control plane.
Features
- Tenant root group: every tenant has one, named after the tenant id with the display name
Tenant Root Group; it cannot be created, updated or deleted. A subscription that was never placed belongs to it, as in Azure. - One hierarchy per tenant: under tenant scoping (on from
parity: azure) the caller's token tenant picks the hierarchy, the way it picks the subscriptionsGET /subscriptionslists: each configured tenant has its own root group, groups and subscriptions, and a subscription cannot be placed in another tenant's hierarchy. A token naming no configured tenant works on the default tenant's. - Groups: CreateOrUpdate (
PUT, withproperties.details.parent.id; the root when omitted), Get with$expand=children(plus$recurse=true),$expand=pathand$expand=ancestors, Update (PATCHofdisplayNameandparentGroupId), Delete (an empty group only), List,descendants. - Subscriptions:
GET/PUT/DELETEmanagementGroups/{group}/subscriptions/{subscriptionId}and thesubscriptionslisting; placing a subscription registers it with the emulator's directory. ADELETEremoves the placement only while the subscription is still under that group (200), and answers204otherwise, so it never undoes a move to another group. Anything belowsubscriptions/{subscriptionId}is not a resource type and answers404 InvalidResourceType. - Entities:
POST /providers/Microsoft.Management/getEntitieswith the parent chains, descendant and child counts, narrowed bygroupName. - Also served:
checkNameAvailability,operations, thesettings/defaultresource and the tenant backfill operations the CLI calls. - Azure error shapes:
NotFoundfor a missing group,InvalidManagementGroupName,InvalidRequestfor a missing parent or a move under a descendant,Conflictwhen deleting a group with children.
Endpoints
GET /providers/Microsoft.Management/managementGroups
GET /providers/Microsoft.Management/managementGroups/{groupId}?$expand=children|path|ancestors&$recurse=true
PUT /providers/Microsoft.Management/managementGroups/{groupId}
PATCH /providers/Microsoft.Management/managementGroups/{groupId}
DELETE /providers/Microsoft.Management/managementGroups/{groupId}
GET /providers/Microsoft.Management/managementGroups/{groupId}/descendants
GET /providers/Microsoft.Management/managementGroups/{groupId}/subscriptions
GET /providers/Microsoft.Management/managementGroups/{groupId}/subscriptions/{subscriptionId}
PUT /providers/Microsoft.Management/managementGroups/{groupId}/subscriptions/{subscriptionId}
DELETE /providers/Microsoft.Management/managementGroups/{groupId}/subscriptions/{subscriptionId}
GET /providers/Microsoft.Management/managementGroups/{groupId}/settings[/default]
POST /providers/Microsoft.Management/getEntities
POST /providers/Microsoft.Management/checkNameAvailability
GET /providers/Microsoft.Management/operations
Any api-version is accepted (the shapes follow 2023-04-01).
Quickstart
BASE=http://localhost:4577/providers/Microsoft.Management
curl -s -X PUT "$BASE/managementGroups/platform?api-version=2023-04-01" -H "Content-Type: application/json" \
-d '{"properties": {"displayName": "Platform"}}'
curl -s -X PUT "$BASE/managementGroups/corp?api-version=2023-04-01" -H "Content-Type: application/json" \
-d '{"properties": {"displayName": "Corp", "details": {"parent": {"id": "/providers/Microsoft.Management/managementGroups/platform"}}}}'
curl -s -X PUT "$BASE/managementGroups/corp/subscriptions/00000000-0000-0000-0000-000000000001?api-version=2023-04-01"
curl -s "$BASE/managementGroups/platform?api-version=2023-04-01&\$expand=children&\$recurse=true" | jq .
az account management-group create --name platform --display-name Platform
az account management-group subscription add --name platform --subscription 00000000-0000-0000-0000-000000000001
az account management-group show --name platform --expand --recurse
Configuration
| Property | Env var | Default | Description |
|---|---|---|---|
enabled |
FLOCI_AZ_SERVICES_MANAGEMENT_GROUPS_ENABLED |
true |
Serves the Microsoft.Management management-group resources. When disabled, their paths fall through to the generic ARM handler and answer 404 |
Intentional deviations
- Creates and deletes answer synchronously (
200/204) rather than as the long-running operations Azure may answer with202; both are allowed by the service contract and every client handles the synchronous answer. - Policy assignments at management-group scope are stored, not inherited. The policy control plane accepts a management group as a scope without consulting this hierarchy; a hierarchy-aware evaluation of management-group assignments is a separate change.
- No role-based scoping:
getEntitiesreportsviewpermissions on everything andinheritedPermissionslikewise;$filter,$search,$view,$select,$skip,$topand$skiptokenongetEntitiesand the listings are accepted and ignored (every entity is returned). updatedByis null andversioncounts writes; Azure stamps the caller and its own version.- Settings (
settings/default) are a fixed representation:requireAuthorizationForGroupCreationis alwaysfalseand writes are acknowledged without being stored.