The ticket
Auditor: “Where does pay-api live?” Junior: a subscription named Ram-PayPal with Owner = a Hotmail. No Policy. No MG. That is not a landing zone. That is a credit card with a VM.
An Azure landing zone (CAF Ready) is a pre-provisioned environment: management group hierarchy, subscriptions for platform vs workloads, identity, networking, and Azure Policy so a workload cannot skip the rails. Hub networking sits in a platform/connectivity subscription (sub-hub). The app sits in a workload subscription (sub-spoke-app) under a landing-zone MG. Do not give standing Owner to a personal account.
Tenant techclick-lab.in · MG tc-root / tc-landing / tc-workloads · subs sub-hub sub-spoke-app · hub VNet 10.40.0.0/16 · spoke 10.41.0.0/16 · Azure Firewall 10.40.0.4 · VPN GW public 203.0.113.50 · on-prem FortiGate WAN 203.0.113.10. Not a live tenant.
Mental model
| Object | Job | This lab |
|---|---|---|
| Management group | Folder for Policy + RBAC inheritance | tc-root → tc-landing / tc-workloads |
| Subscription | Billing + deploy scale unit | sub-hub (platform), sub-spoke-app (workload) |
| Azure Policy | Guardrail (deny / audit / deploy-if-not-exists) | Assigned at tc-workloads |
| Resource group | Lifecycle of related resources | Not a security boundary by itself |
Inherit Policy downward. Do not attach production to the tenant root with Owner.
How to choose
| Need | Put it | Do not |
|---|---|---|
| Firewall, VPN GW, Bastion | sub-hub under tc-landing | Inside the app RG “for speed” |
| pay-api | sub-spoke-app under tc-workloads | A personal subscription |
| Deny public IPs | Policy on tc-workloads | A sticky note to the intern |
Hierarchy
Runbook
Side A — tree
Portal → Management groups. Confirm
sub-spoke-appparent istc-workloads, not Tenant Root Group.Side B — rails
Policy assignments on
tc-workloads: allowed locations, no public IP on VMs, require diagnostic settings. Then RBAC: groups, not personal Owners.Side C — prove
az account management-group entities listandaz policy assignment list. Then deploy. Not before.
az account management-group entities list -o table # Name Type DisplayName # tc-root ManagementGroup tc-root # tc-landing ManagementGroup tc-landing # tc-workloads ManagementGroup tc-workloads # sub-hub Subscription sub-hub # sub-spoke-app Subscription sub-spoke-app az policy assignment list --scope /providers/Microsoft.Management/managementGroups/tc-workloads -o table
Four failures
1 · Prod VM in a random sub
Today’s ticket. No Policy, personal Owner, no hub peer.
2 · Everything under Tenant Root
One bad Policy assignment becomes a tenant-wide outage. Use intermediate MGs.
3 · Owner on a personal ID
That person leaves. The sub is now an orphan with a stale MSA.
4 · Policy only on the RG
Next RG skips it. Assign at MG or subscription.
How to prove it
1) Parent MG of each sub is named. 2) Policy is at tc-workloads, not a wish. 3) Owner is a group. 4) pay-api was not created first “to test.”
Traps
| Looks like a landing zone | Is not |
|---|---|
| A VNet named “hub” | No MG, no Policy, personal Owner |
| Blueprints folder from 2019 | CAF landing zone is MG + Policy + platform subs |
| Contributor on the whole tenant root | Standing god-mode — use groups + PIM later |
Knowledge check
Judgment items. One best answer. Reasons send you back to the matching section.
Azure security class series: Shared + Entra · Landing zone · NSG vs Firewall vs WAF · Conditional Access · Key Vault + MI · Private Link · Defender + Sentinel · Hub-spoke · Identity path · Interview
Sources
Related: Azure session factory · Migration series.