1.2 The Resource Hierarchy: Where Things Live


Now that we've covered the overarching top level overview of what Azure is conceptually, we can start diving into the weeds. Or should I say...dive into the clouds?...


Anyways, the first step to beginning to understand Azure is how it actually organizes the stuff you'll be working with. There's alot of "things" - services, resources, etc. - that you can spin up in Azure, all of those need to be organized in a way that makes sense. Or else we'd lose our minds trying to make sense of it all in large enterprise environments.


Every resource you ever deploy in Azure (a VM, a storage account, a SQL database, a Logic App, anything) lives somewhere in a four-level hierarchy. Top to bottom, it goes like this:

Sure, it looks simple when you only have a few things in place. The hierarchy is doing more work than it looks like at first glance. Permissions roll down it. Policies roll down it. Costs roll up it. So understanding this hierarchy is crucial in architecting a businesses entire Azure environment. Let's break down the purpose of each level.


The ALMIGHTY Tenant


The four levels above are the resource hierarchy in Azure. All four of them live inside one outer wrapper: the almighty Tenant. The Tenant is your organization's "dedicated, isolated instance of Microsoft's cloud-based identity and access management services." Every Management Group, every Subscription, every Resource Group, every resource is parented to exactly one Tenant and our lovely Mad Hat Labs Azure instance has exactly ONE tenant ID.


And not to get too pedantic, but you'll notice that I might say Azure tenant or Entra tenant interchangeably because Microsoft loves to rename things. ALL. THE. TIME. They're the same thing, just "re-branded" semantics by Microsoft.


The Tenant is the identity boundary which is not technically a resource hierarchy level, but rather it's the outermost ring around everything you'll see in this lesson. We cover the Tenant in detail in Chapter 2 when we get into Entra ID. But for now just know that the resource hierarchy is wrapped inside a tenant, and depending on what permissions you have on the account you authenticate with in that tenant determines what hierarchy you see.


Management Groups: The Wrapper Around Your Subscriptions


A Management Group is a container for one or more subscriptions. It exists for exactly one reason: to keep one's sanity as your Azure instance scales. When you have more than a handful of subscriptions you need a way to apply governance with security policies, RBAC role assignments, cost views, etc. across all of them without manually doing it one subscription at a time. Doing the same thing 200 times is how you get an aneurysm.


At the very top of every Entra tenant, Microsoft automatically creates a special Management Group called the Tenant Root Group. Every subscription you create gets parented to it by default and you can nest more Management Groups underneath to organize subscriptions however you want.


A common pattern looks like this:

If your security team wants to enforce a policy that says "no public IP addresses can be created in any production workload," they can just apply it to the Production MG one time. Both Prod-Workload-1 and Prod-Workload-2 will inherit it automatically. And if new subscriptions get added to Production tomorrow? They inherit it too and there's no per-subscription mind-numbing clicking needed. You might start to realize how this concept of inheritance might cause "security" issues down the line if you're not careful.


Microsoft caps you at six levels of nesting under the root group. But, you should never get close to that limit unless you really like building org charts.


Subscriptions: The Billing & Security Boundary


A subscription can be thought of as two IMPORTANT things. First, it's the billing boundary. Every Azure resource is billed to exactly one subscription. When you create a subscription it's tied to a billing account and payment method. When you spin up a VM, the meter for that VM ticks against its parent subscription's bill. And if that's your credit card, better hope you've got budget alerts in place...just in case. Second, it's a security boundary. RBAC (Role-Based Access Control) role assignments at the subscription level apply to everything inside that subscription (remember inheritance), and quota limits (how many VMs you can create, how many vCPUs you can consume, etc.) are scoped per subscription.


You'll hear a term thrown around constantly in cloud security: blast radius. Pretty much everywhere in cybersec actually. The blast radius of a compromised identity is defined by answering this question: If this account gets pwned, how far can the attacker reach? An identity scoped at the Subscription level has a blast radius of the entire subscription and what role they were assigned.


If you're curious how many roles we're talking, check out Microsoft's documentation: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles


There's a lot...


An identity scoped at a single Resource Group has a blast radius of that one RG and everything under it. The way you keep blast radius small is by aggressively splitting workloads into separate subscriptions and scoping individual accounts to the tightest piece of the hierarchy they can still do their job from. A developer doesn't need Owner on the whole subscription. They need Contributor on the one Resource Group their app lives in. It all goes back to the principle of least privilege aiming for smallest scope needed to get the job done and it's the single most repeated piece of advice in cybersecurity. Chapter 3 goes deep into the mess that is RBAC and Privileged Access. I've worked with Azure roles for years and am still referencing documentation to ensure permissions are kept at a minimum.


Every subscription has a unique ID, a GUID (Globally Unique Identifier), that you'll see constantly. Probably won't memorize it, but worth noting where in Azure you can view the ID. Every Azure CLI command, every ARM template, every API call wants to know which subscription you're operating in. The fastest way to find it from a Azure CLI terminal is az account show. It's displayed in a lot of places as well in many of the Microsoft portals tied to your tenant. The fastest way to find it from the Azure portal is to type "Subscriptions" in the top search bar.


A single tenant can have a stupid number of subscriptions. Big enterprises routinely have hundreds and just to give some examples of the common use cases for splitting them up:


  • By environment. Production, Staging, Dev, Test.
  • By business unit. Marketing, Engineering, Sales, Operations.
  • By application. One subscription per app for hard isolation.
  • By regulation. A subscription scoped only to PCI-compliant workloads, another for HIPAA, etc.


For Mad Hat Labs, every operative is sharing one subscription inside the Mad Hat Labs tenant. Behave operatives...Your operative account is scoped down so you can only see and do things in your own resource group. For now. I may change things as I go along.


Resource Groups: The "Folder" You Actually Live In


A Resource Group is the lowest level of organization above an individual resource. It can be thought of as a folder more or less. Resources inside a RG (resource group, duh...) can talk to each other, share lifecycles, and inherit RBAC assignments and tags applied at the RG level.


Things to know about Resource Groups that will save you from infinite pain:


  • A resource belongs to exactly one RG. Always. No exceptions.
  • You pick the RG's region when you create it, but the RG's region is just where the RG metadata lives. The resources inside can be in different regions if needed. It can become a bit of a mess. Most of the time you keep them all in the same region for sanity sake.
  • Deleting an RG deletes everything inside it. SOOOO, be careful obviously. This is the single most useful cleanup mechanism in Azure. Built a lab? Want it gone? Delete the RG. Done. This is also exactly how you accidentally torch production and cause a job-altering life moment. So, always check what subscription you're in first and what exactly lives underneath it.
  • RGs do not nest. You cannot put one RG inside another. Resource Groups are flat. In parallel. Same plain. You get it...hopefully...


The naming convention is one of those things that seems trivial until you have 400 of them. Microsoft's recommendation is rg-<workload>-<environment>-<region>-<instance> so you end up with names like rg-webapp-prod-eastus-001. It looks ugly I know. Nobody loves it. At first...But, when you're hunting through hundreds of RGs in a real environment, it grows on you.


Resources: The Things That Actually Cost You Money


A resource is anything Azure manages for you. VMs, storage accounts, SQL databases, virtual networks, Key Vaults, Function Apps, Sentinel workspaces, SO MANY THINGS. There are thousands of resource types. Every resource has a fully qualified resource ID that looks like this:

That string is the unambiguous Azure-wide identifier for one specific resource. When you assign an RBAC role, when you reference a resource in an ARM template, when you query a resource in Azure Resource Graph, the resource ID in all it's lengthy glory must be exact. Or else things break or error messages pop up. You'll get used to those.


Two Kinds of ID You'll Confuse for a While


Azure has two flavors of identifier and beginners mix them up constantly. They look almost identical because both are GUIDs.


Object IDs belong to identities. Every user, every group, every service principal, every managed identity in Microsoft Entra ID gets an Object ID when it's created. When you assign an RBAC role to someone, the backend stores the assignment using the Object ID. It doesn't use their email or display name because that would be silly. Rename the user tomorrow? Their Object ID stays the same. The Object ID is the durable handle that allows for changing properties on the Object ID without breaking everything.


Resource IDs belong to Azure resources. They're the long slash-delimited path you saw above, ending in the resource's name. Every VM, every storage account, every Key Vault, every Logic App has one.


When an RBAC role assignment exists in Azure, it pairs an Object ID (who) with a Resource ID or scope (what they're allowed to do it on). If you mix the two up in a conversation, god forbid an interview, and they'll know you're new. But that's ok, Azure can be a mess. Get them straight and you'll already sound more senior than half the room. Say it confidence!


Inheritance: The Most Important Thing in This Lesson


Now we get to why the hierarchy actually matters. Three things flow down the hierarchy from top to bottom:


RBAC role assignments inherit downward. Assign someone the Reader role on a Management Group and they're Reader on every subscription, every RG, every resource underneath. If you assign them Reader on a single Resource then that's where it stops.


Azure Policy assignments inherit downward. Apply a policy at the Tenant Root Group that says "deny VMs that aren't in approved sizes," and that policy applies to every resource in every subscription in every RG underneath. If you apply it to a single RG then only that RG's resources are evaluated and will be affected by the policy.


Tags can inherit downward via tag inheritance policies. Apply a tag at the subscription level and child resources can be configured to receive it automatically.


This inheritance is the entire reason the hierarchy exists. The reason your security team wants every subscription to live under a proper Management Group is so they can apply controls once and have those controls propagate everywhere they need to be.


Cost rolls UPWARD instead. A cost report at the subscription level shows the sum of every resource inside it. A cost report at a Management Group level shows the sum of every subscription underneath. So, when finance asks "what did the Production environment cost us this month?" you can point Azure Cost Management at the Production Management Group and get a clean number. Easy.


Why Operatives Care


For a security analyst the hierarchy is important when investigating detections and access. Say you want to query "any privileged role assignment on a production subscription in the last 30 days." That query is only possible if you have a clean hierarchy with a Production MG to scope against. A messy hierarchy where everything is dumped into the Tenant Root Group makes every detection sloppy and every audit miserable.


For a junior engineer, the hierarchy is where you avoid blowing up production. The number of incidents that start with "I thought I was in the Dev subscription" is significantly less than zero. Look at your active subscription before every command. az account show is your friend. Make peace with it.


For attackers, the hierarchy is the map. Once they compromise an identity, the first thing they do is enumerate the hierarchy with az account list, az group list, az resource list. On an unrelated note, I was able to have an AI Agent enumerate this hierarchy nice and easy with those exact commands. Neat huh? Attackers want to know what they can see, what they can touch, and what they can pivot into. The smaller the blast radius of any single identity, the harder this is for them. Which is why scoping RBAC tightly at the RG level instead of the subscription level matters. These minor details matter in a "keep your job" way.


Time for Some Reconnaissance


You're not building anything in this lesson. Your mission right now Operative is reconnaissance. Drop into the live tenant, look at what's already there, and extract the IDs and properties that prove you understand the hierarchy. As mentioned, this is exactly what an attacker does in the first hour of every cloud compromise. You're just doing it through the GUI (Graphical User Interface). It's also what a brand new analyst does on their first day. They click around Microsoft portals and pretend their job is difficult then reach out to an engineer when they can't access something...But yea, attacker or analyst - same skill set in Azure, just opposite intentions.


Deploy your lab environment if you haven't already with the [ DEPLOY LAB ENVIRONMENT ] button below, then sign into portal.azure.com with your operative credentials. Once you're in the Mad Hat Labs tenant, complete the two recon missions.