Part 1: Build Azure Resource Hierarchy
Create and query Azure resource groups to map management scope and regions.
Introduction
30 Second Summary
Long lists of similar labels can make a simple structure feel harder than it is. The confusion shows up the moment someone asks who controls a workload or where it runs.
In this project, you will build a live Azure organization for a fictional application in the Azure portal. You will query its management hierarchy with Azure Resource Graph Explorer before mapping the workload's physical placement.
What You'll Build
Picture opening one Azure dashboard where the journey from management scope to physical region is ready for an AZ-900 demonstration.
By the end of this project, you'll have:
- Two live resource groups that make separate development and production lifecycles visible in the portal.
- A query-backed inventory where Resources exposes deployable items while ResourceContainers reveals the containers around them. You can match the result to the active subscription.
- A placement record that classifies your chosen region by geography, physical location, region pair, support for availability zones, and cloud type. A saved dashboard keeps the hierarchy ready to demonstrate.
- Secret Mission: Flatten the subscription's visible management-group ancestor chain. Export the result as CSV evidence.
Are there any prerequisites?
You need an active Azure subscription with permission to create resource groups.
No local installation is required.
Before We Start
Before you build the live Azure hierarchy, this checkpoint gives its development and production environments a concrete workload to represent. Your choice will anchor why each environment needs its own lifecycle.
Validate Your Azure Workspace
Your fictional workload needs a clear Azure subscription boundary before any containers are created. A wrong choice places future resource groups inside the wrong billing boundary or access boundary.
This step uses the Azure portal to identify your target subscription. You then inspect the upper hierarchy before proving that Azure Resource Graph Explorer can query the chosen scope.
In this step, get ready to:
- Select the active subscription that will contain your project resource groups.
- Inspect the visible management groups without changing the hierarchy.
- Run a Resource Graph query against the target subscription.
Confirm the target subscription
A subscription is a management unit that acts as a billing boundary. It also defines an access-control boundary for the resources you create inside it.
Why Use the Portal?
The portal keeps subscription details, hierarchy visibility, and Resource Graph in one browser workspace. This removes local setup from the project.
- Go to the Azure portal in your browser.
- Sign in with the account connected to your active Azure subscription.
- Enter Subscriptions in the search bar at the top of the portal.
- Select Subscriptions from the search results.
- Select the active subscription you want to use for this project.
- Record the displayed subscription name here: your target subscription name.
- Record the displayed Subscription ID here: your target subscription ID.
Good, the selected subscription now gives every later resource group a known billing boundary. Its recorded ID gives you an exact value for later query comparison.
Inspect the visible upper hierarchy
Management groups provide a governance scope above subscriptions. Your role determines which parts of that upper hierarchy you can inspect.
This inspection leaves the hierarchy unchanged. You only need evidence of what your current role can view.
- Select All services from the Azure portal menu.
- Enter Management groups in the service search field.
- Select Management groups to open the hierarchy page.
- Review the management groups visible to your role.
- Review the subscriptions shown beneath the visible management groups.
- Check whether a details link is available for each visible management group.
- Leave every management group and subscription in its current position.
Your view now reveals how much of the upper hierarchy your role exposes. An unavailable details link records a visibility boundary instead of a project failure.
Validate Azure Resource Graph Explorer
Resource Graph Explorer uses Kusto Query Language to search Azure resources across a selected scope. This first query counts the resource records that your target subscription exposes.
- Enter resource graph in the Azure portal search bar.
- Select Resource Graph Explorer from the search results.
- Select Directory if the current query scope includes more than the target subscription.
- Limit the query scope to your target subscription name.
- Replace the query editor contents by pasting the query below:
Resources
| summarize count()
What Does This Query Do?
- The Resources table contains most Azure Resource Manager resource types within the selected scope.
- The summarize count() operation reduces those records to one numeric total.
Before you select Run query, do you expect the count to be zero or greater than zero for this subscription?
- Select Run query above the query editor.
The Results tab displays one numeric resource count.
- Select Results to confirm that the output contains a numeric resource count.
- Select Messages to review the result count.
- Review the query duration in Messages.
- Check Messages for any errors.
That is the workspace check complete. Resource Graph can read the chosen subscription scope.
Query Not Returning a Number?
- Confirm that the selected scope names your target subscription name.
- Check that Resources is the first line of the query.
- Check that | summarize count() is the second line of the query.
Help me troubleshoot my Azure Resource Graph query.
Your subscription scope is confirmed, your hierarchy visibility is recorded, and Resource Graph is responding. Next, you will create the development and production containers inside this validated boundary.
Create Lifecycle Resource Groups
Your target subscription is selected in the Azure portal.
Development changes need a flexible lifecycle. Production releases need a controlled lifecycle.
A resource group is a management container for related resources. You will create one empty group for each lifecycle under the same subscription.
In this step, get ready to:
- Create an empty development resource group in your selected region.
- Create an empty production resource group in the same region.
- Record the direct subscription placement of both groups without nesting.
Create the development resource group
The development group becomes the first lifecycle boundary for your fictional workload. Its selected Azure region stores the group's management metadata.
What does an empty group create?
This action creates only a management container. It starts no metered compute, networking, or storage service.
- Switch back to the Azure portal from earlier.
- Enter Resource groups in the portal search bar.
- Select Resource groups from the search results.
The Resource groups page is where your two lifecycle containers will appear.
- Select Create.
- Choose the target subscription you recorded earlier in Subscription.
The form now points to the billing and access boundary you verified earlier.
- Enter az900-architecture-dev-rg in Resource group.
- Choose an Azure region near you in Region.
The selected location belongs to the resource group's metadata.
- Record the selected value here: your selected Azure region.
- Select Review + Create.
The review screen should confirm that the subscription, group name, and region are ready for creation.
- Select Create.
Good, your first lifecycle container is live. Its successful creation confirms that your account can create resource groups in the target subscription.
- Select Go to resource group from the notification.
You should see az900-architecture-dev-rg on its overview. The subscription and location should match your recorded choices.
Development group creation failed?
- Check that the selected subscription matches the target subscription you recorded earlier.
- Ask your subscription administrator for permission to create resource groups if the portal reports a permission problem.
- Help me troubleshoot this resource group creation problem.
Create the production resource group
The production group gives releases a separate lifecycle boundary. Using the same metadata location keeps the two groups easy to compare.
- Return to the Resource groups page from earlier.
- Select Create.
- Choose the target subscription you recorded earlier in Subscription.
The production group now starts from the same subscription boundary as the development group.
- Enter az900-architecture-prod-rg in Resource group.
- Select your selected Azure region in Region.
The two resource groups now use the same metadata location.
- Select Review + Create.
The review screen should confirm the production group values.
- Select Create.
That second container is ready. Your development and production environments now have separate lifecycle boundaries.
Production group missing?
- Check that the group name is exactly az900-architecture-prod-rg.
- Confirm that the creation form still points to your recorded target subscription.
- Help me troubleshoot the missing production resource group.
Verify the hierarchy placement
Both resource groups should sit directly below the target subscription. Azure resource groups cannot be nested inside other resource groups.
- Return to the Resource groups page from earlier.
- Select az900-architecture-dev-rg.
- Review the subscription shown on the group overview.
- Compare the displayed location with your selected Azure region.
The development group belongs directly to your target subscription. Its location matches your recorded region.
- Return to the Resource groups page.
- Select az900-architecture-prod-rg.
- Review the subscription shown on the group overview.
- Compare the displayed location with your selected Azure region.
The production group has the same direct parent. Its location also matches your recorded region.
- Record this hierarchy finding: az900-architecture-dev-rg belongs directly to the target subscription. az900-architecture-prod-rg belongs directly to the target subscription. Azure resource groups cannot be nested.
- Return to the Resource groups page from earlier.
Before you refresh, do you expect both lifecycle group names to appear under your target subscription?
- Select Refresh.
You should see az900-architecture-dev-rg and az900-architecture-prod-rg under the intended subscription.
Both lifecycle containers are now visible in your Azure hierarchy. Next, you will test whether a resource inventory can see them.
Expose the Resource Inventory Gap
Your two lifecycle groups now sit directly under the target subscription in the Azure portal.
A useful hierarchy inventory must account for deployable resources plus management containers. In this step, you will test whether a standard query in Azure Resource Graph Explorer can show both.
In this step, get ready to:
- Run a sorted inventory of deployable Azure resources.
- Compare the query output with the two resource groups visible in the portal.
- Record the inventory boundary exposed by the comparison.
Run the sorted resource query
A projection creates a compact inventory by selecting specific fields from each result. Sorting those results by name makes the portal comparison easier.
- Return to Azure Resource Graph Explorer from earlier.
- Select the existing query in the query editor.
- Replace the selected query by pasting this query:
Resources
| project name, type, location
| order by name asc
What Does This Query Do?
- The project operator keeps the name, type, and location fields for each returned record.
- The order by name asc expression sorts the inventory by resource name in ascending order.
Before you run the query, decide whether the two empty resource groups will appear as rows.
- Select Run query in the query toolbar.
You will see the Results tab refresh. Returned rows show the name, type, and location columns in ascending name order.
Query Results Look Unexpected?
- Check Messages to confirm that the query completed when Results is empty.
- Use Directory to confirm that the selected scope is your target subscription.
- Help me troubleshoot this Resource Graph query.
Compare the inventory with the portal
The portal provides the control view for this test. Matching it against the query reveals whether the inventory includes your empty management containers.
- Switch back to the Resource groups page from earlier.
- Select Refresh in the page toolbar.
- Confirm that az900-architecture-dev-rg appears under the target subscription.
- Confirm that az900-architecture-prod-rg appears under the target subscription.
- Return to the Results tab in Azure Resource Graph Explorer.
- Check the name column for az900-architecture-dev-rg.
- Check the name column for az900-architecture-prod-rg.
Neither az900-architecture-dev-rg nor az900-architecture-prod-rg appears as a row in Results. This is the intended inventory gap.
Good catch. Your portal has two live containers that the resource-focused inventory leaves out.
Cannot Reproduce the Gap?
- Confirm that Azure Resource Graph Explorer uses the same target subscription as the Resource groups page.
- Rerun the exact sorted query shown above.
- Help me compare my Resource Graph results with my resource groups.
Record the table boundary
The Resources table is the default table for most deployable Azure Resource Manager resource types. It provides a resource inventory within the selected scope.
Management hierarchy containers are represented in ResourceContainers. Your empty resource groups remain part of the subscription hierarchy even though the sorted Resources query does not return them.
✔️ Awesome, I've got everything!
Your query matches the sorted resource inventory used for this comparison.
ⓧ I'd like to double check the full code
Compare your query with this complete sorted resource inventory query.
Resources
| project name, type, location
| order by name asc
Your hierarchy test now has evidence of the missing-container gap. Next, you will bring management containers into the query view so the inventory can explain more of the Azure hierarchy.
Query the Full Management Scope
You proved that the two empty resource groups exist in the Azure portal. The sorted Resources result omits both containers.
That gap keeps a resource-only inventory from explaining the full management hierarchy. Azure Resource Graph closes it by querying ResourceContainers alongside Resources.
In this step, get ready to:
- Run a combined query that displays resource-group containers beside deployable resources.
- Verify the target subscription against its recorded identity.
- Record the complete Azure management scope chain.
Combine containers with resources
The ResourceContainers table holds hierarchy containers. A union can place a sample of those containers beside a sample of deployable resources.
Before you run the combined query, which table do you expect to return the empty groups? Hold that prediction while you test it.
- Switch back to Resource Graph Explorer from earlier.
- Select the existing query text in the query editor.
- Replace the selected text by pasting this query:
ResourceContainers
| where type=='microsoft.resources/subscriptions/resourcegroups' | project name, type | limit 5
| union (Resources | project name, type | limit 5)
What Does This Query Do?
- The where clause filters ResourceContainers to resource-group container rows.
- The project clause keeps two columns: name plus type.
- The limit 5 clause caps each branch at five sample rows.
- The union clause appends the deployable-resource sample to the container sample.
- Select Run query above the query editor.
- Review the type column in the Results tab.
You should see resource-group container rows whose type is microsoft.resources/subscriptions/resourcegroups. You should also see deployable-resource rows when the subscription contains resources.
That gap is now closed: your live inventory shows containers beside deployable resources.
Missing the Resource-Group Rows?
- Confirm that Resource Graph Explorer still uses the target subscription scope.
- Return to the Resource groups page from earlier to confirm that both project groups remain visible.
- Ask for help with missing resource-group rows.
Identify the subscription boundary
A subscription is the billing boundary above your resource groups. It also defines an access-control boundary for the resources below it.
Before you run the lookup, do you expect its identity to match the subscription details you recorded earlier? Keep that prediction in mind during the comparison.
- Select the combined query in the query editor.
- Replace the selected text by pasting this subscription lookup:
ResourceContainers
| where type =~ 'microsoft.resources/subscriptions'
| project subscriptionId, name
What Does This Query Do?
- The where clause filters ResourceContainers to subscription rows.
- The =~ operator matches the subscription type without case sensitivity.
- The project clause keeps subscriptionId plus name for comparison.
- Select Run query above the query editor.
- Compare the returned name plus subscriptionId values with the subscription details recorded earlier.
You should see the target subscription name with its matching Subscription ID. This confirms that the query scope points to the intended billing and access boundary.
You have now verified the subscription above both project resource groups.
Subscription Details Do Not Match?
- Confirm that the query scope still targets the subscription selected earlier.
- Compare the returned Subscription ID character by character with the recorded value.
- Ask for help with a Resource Graph subscription mismatch.
✔️ Awesome, I've got everything!
Both queries have run successfully. The target subscription identity matches the values recorded earlier.
ⓧ I'd like to double check the full code
These are the two complete queries from this step.
Combined hierarchy query.
ResourceContainers
| where type=='microsoft.resources/subscriptions/resourcegroups' | project name, type | limit 5
| union (Resources | project name, type | limit 5)
Subscription lookup query.
ResourceContainers
| where type =~ 'microsoft.resources/subscriptions'
| project subscriptionId, name
Assemble the management hierarchy
A management group provides governance above subscriptions. Lower management scopes can inherit settings assigned higher in the hierarchy.
How Does the Scope Chain Work?
- Management groups organize subscriptions under shared governance.
- Subscriptions define billing and access-control boundaries.
- Resource groups collect related resources under one lifecycle.
- Each resource belongs to one resource group.
- Add this scope chain to the record where you captured the earlier Resources limitation: management group > subscription > resource group > resource.
- Add that settings assigned at a higher management scope can be inherited by lower scopes.
- Add that each resource belongs to one resource group.
Before you check the finished record, which result proves the resource-group level? Which result proves the subscription level? Use the evidence to test your answer.
- Compare the combined query result with the management scope chain in your record.
- Compare the subscription lookup result with the subscription values recorded earlier.
In the combined result, you should see rows of type microsoft.resources/subscriptions/resourcegroups beside deployable-resource rows. In the subscription lookup, you should see the recorded target subscription name with its Subscription ID.
Your evidence now supports every management level from the visible management-group boundary down to individual resources.
Your query-backed inventory now connects deployable resources to their management containers. Next, you will connect this logical hierarchy to Azure's physical architecture.
Map Physical Azure Placement
Your Azure Resource Graph inventory now shows the management scope around your resource groups. That management view still leaves a different AZ-900 question unanswered: where Azure hosts workloads and how that placement supports resilience.
Azure's physical architecture organizes placement through geographies, regions, availability zones, and datacenters. You will classify the selected region before saving your hierarchy query as dashboard evidence.
In this step, get ready to:
- Classify the selected region by geography, physical location, region pair, availability-zone support, and cloud type.
- Record parallel management and physical architecture chains.
- Save the combined hierarchy query and pin its result to an Azure dashboard.
Classify the selected region
A placement record connects your selected Azure region to its geography and resilience context. It also identifies whether the region belongs to Azure's public cloud or a sovereign cloud.
How does Azure describe physical placement?
The Azure regions reference connects each region to a geography, physical location, programmatic name, paired status, and availability-zone status.
An availability zone is a logical grouping of one or more physically separate datacenters within a region. It has independent power, cooling, and networking infrastructure.
Some regions are nonpaired and use availability zones as a primary redundancy mechanism. A paired region does not automatically provide high availability, disaster recovery, or failover.
- Switch back to the Resource groups page from earlier.
- Select az900-architecture-dev-rg from the resource-group list.
- Record the region shown on the overview here: your selected Azure region.
- Open Microsoft's current List of Azure regions.
- Find the row for your selected Azure region.
- Collect its Programmatic name, Geography, Physical location, and Paired region values for the checkpoint below.
- Confirm its zone status from the Availability zone support field.
- Classify your selected Azure region as public-cloud or sovereign-cloud by comparing it with the linked sovereign region lists.
You now have a placement record that connects the region name you selected in the portal to Azure's current architecture reference.
Separate management scope from physical placement
Management scope describes the governance path around an Azure resource. Physical placement describes the location path that reaches the datacenters hosting deployed services.
Why keep the chains separate?
A region is not a parent of a subscription or resource group. Azure uses management scopes to organize access, billing, policy, and lifecycle.
A resource group's location stores its management metadata. Resources inside that group can still be deployed to different regions.
- Enter management group > subscription > resource group > resource as the management chain in the checkpoint below.
- Enter geography > region > availability zone > datacenter as the physical chain in the checkpoint below.
- Add a note that the resource-group location stores management metadata.
- Add a note that resources in one group can be deployed to different regions.
That distinction is now explicit. You can explain who governs a workload without confusing management scope with its physical hosting location.
Save and pin the hierarchy evidence
The Azure Resource Graph Explorer can preserve the exact union query as a private query. The Azure portal can pin its rerun result to a dashboard for later demonstrations.
- Switch back to Resource Graph Explorer from earlier.
- Replace the current editor contents with the documented combined query:
ResourceContainers
| where type=='microsoft.resources/subscriptions/resourcegroups' | project name, type | limit 5
| union (Resources | project name, type | limit 5)
What does this query preserve?
- The ResourceContainers section selects up to five resource-group container rows.
- The union operator combines those rows with up to five deployable-resource rows from Resources.
- The shared name and type columns let you distinguish the two row categories.
- Select Save above the query editor.
- Enter AZ-900 Resource Hierarchy as the query name.
- Choose Private queries as the save location.
- Select Save to preserve the query.
Before you rerun the saved query, predict which row types you expect to return.
- Select Run query to verify the saved query.
The Results tab shows resource-group container rows alongside any deployable-resource rows available in the selected subscription.
The portal may ask you to choose a dashboard destination when you pin the result.
- Select Pin to dashboard above the rerun result.
- Choose the Azure dashboard you want to use if a destination prompt appears.
Before you check the dashboard, predict where the new hierarchy evidence should appear.
- Navigate to the Azure portal dashboard that received the tile.
You should see a pinned tile from the rerun AZ-900 Resource Hierarchy result. The tile gives you a saved hierarchy view for AZ-900 revision.
Can't save or pin the query?
- Confirm Resource Graph Explorer remains scoped to the target subscription.
- Rerun the query if the dashboard pin control is unavailable after editing or saving.
- Wait for the Results tab to populate before trying to pin the result.
- help me troubleshoot saving or pinning my Azure Resource Graph query
✔️ Awesome, I've got everything!
Your private query is saved as AZ-900 Resource Hierarchy. Its rerun result is pinned to your Azure portal dashboard.
ⓧ I'd like to double check the full code
Compare your saved private query with this exact combined hierarchy query.
ResourceContainers
| where type=='microsoft.resources/subscriptions/resourcegroups' | project name, type | limit 5
| union (Resources | project name, type | limit 5)
What should I compare?
Your saved query should contain the same table names, type filter, projected columns, row limits, and union structure shown here.
You have turned Azure's logical hierarchy and physical architecture into evidence you can inspect from one dashboard.
Secret mission
Reveal the Management Group Ancestors
Flatten the target subscription's nested management-group ancestor chain into ordered rows. Export the result as a CSV so you can prove the governance path your role can see.
Clean Up Your Resources
Clean Up Your Resources
No metered service resources were created, so the remaining artifacts have no ongoing cost. Choose whether to keep them available, pause by signing out, or delete them entirely.
Resources you used:
- An empty Azure resource group named az900-architecture-dev-rg in the selected subscription.
- An empty Azure resource group named az900-architecture-prod-rg in the selected subscription.
- A saved private Azure Resource Graph Explorer query named AZ-900 Resource Hierarchy.
- An Azure portal dashboard tile pinned from the hierarchy query results.
- A downloaded CSV file containing the visible management-group ancestor chain.
Keep everything running
No action needed. Choose this if you want to reuse the hierarchy during future AZ-900 study sessions.
- The empty az900-architecture-dev-rg resource group remains available.
- The empty az900-architecture-prod-rg resource group remains available.
- The private AZ-900 Resource Hierarchy query remains available in Azure Resource Graph Explorer.
- The pinned dashboard tile remains available in the Azure portal.
- The management-group hierarchy CSV remains on your computer.
Pause - I'll come back to this later
There is no running workload to stop. This option keeps every artifact available for your next study session.
- Leave az900-architecture-dev-rg in the selected subscription.
- Leave az900-architecture-prod-rg in the selected subscription.
- Keep the private AZ-900 Resource Hierarchy query.
- Keep the pinned dashboard tile.
- Keep the downloaded management-group hierarchy CSV.
- Sign out of the Azure portal.
Delete - I don't want to use this again
Remove every teardownable project artifact to start fresh. Deleting resource groups is permanent. Empty groups contain no workload resources, so this cleanup removes only the project containers.
Delete the resource groups:
- Return to Resource groups in the Azure portal from earlier.
- Select az900-architecture-dev-rg.
- Confirm that az900-architecture-dev-rg is still empty.
- Select Delete resource group.
- Return to Resource groups in the Azure portal.
- Select az900-architecture-prod-rg.
- Confirm that az900-architecture-prod-rg is still empty.
- Select Delete resource group.
Delete the saved query:
- Return to Azure Resource Graph Explorer from earlier.
- Select the saved private AZ-900 Resource Hierarchy query.
- Select the rubbish-bin icon to delete the query.
Remove the dashboard tile:
- Return to the Azure portal dashboard that contains the pinned query result.
- Select the tile's ellipsis menu.
- Remove the pinned query-result tile.
- Select Save.
Delete the CSV export:
- Use your browser's download history to locate the management-group hierarchy CSV.
- Open the CSV file's containing folder.
- Delete the management-group hierarchy CSV file.
Nice Work!
Nice Work!
That is a wrap! You built a live hierarchy in the Azure portal that connects a selected subscription to separate development and production lifecycles.
You've learned how to:
- Created separate development and production resource groups directly under your selected subscription. Their empty state makes the lifecycle boundary visible without deploying a billable workload.
- Used Azure Resource Graph to expose the gap in a resource-only inventory. Your saved query and dashboard tile show ResourceContainers beside deployable resources from Resources.
- Mapped management scope from management group to subscription to resource group to resource. Compared that chain with physical placement from geography to region to availability zone to datacenter.
- Secret Mission: Flattened the visible management-group ancestor chain with extend and mv-expand. Exported the result as a CSV record of the governance path or its permissions boundary.
Ready to quiz yourself?