Skip to main content

Azure Landing Zones — Enterprise-Scale Architecture

· 7 min read
Goel Academy
DevOps & Cloud Learning Hub

You have been given the green light to migrate 200 workloads to Azure. You create a subscription, deploy a VNet, spin up a few VMs, and everything works. Six months later you have 47 subscriptions with overlapping IP ranges, no consistent naming, three different firewall configurations, and a security team that refuses to sign off on anything. Azure Landing Zones exist to prevent exactly this nightmare — they give you a prescriptive, battle-tested foundation before a single workload moves to the cloud.

What Is an Azure Landing Zone?

A landing zone is a pre-configured Azure environment that provides identity, networking, security, governance, and management foundations for hosting workloads. Think of it as the runway your applications land on — if the runway is built correctly, every plane (workload) that touches down has guardrails, monitoring, and connectivity from day one.

Microsoft's Cloud Adoption Framework (CAF) defines two implementation options:

ApproachBest ForComplexityTime to Deploy
Start Small and ExpandSmall teams, < 10 subscriptionsLowHours
Enterprise-ScaleLarge orgs, regulated industriesHighDays to weeks

This post focuses on the enterprise-scale approach because that is where real-world complexity lives.

Management Group Hierarchy

The management group hierarchy is the backbone of governance. It determines where policies, RBAC roles, and budgets are inherited.

Tenant Root Group
└── Intermediate Root (your org)
├── Platform
│ ├── Identity
│ ├── Management
│ └── Connectivity
├── Landing Zones
│ ├── Production
│ └── Non-Production
├── Sandbox
└── Decommissioned

Create this hierarchy with the Azure CLI:

# Create the intermediate root management group
az account management-group create \
--name "contoso" \
--display-name "Contoso Organization"

# Platform management groups
az account management-group create --name "contoso-platform" \
--display-name "Platform" --parent "contoso"
az account management-group create --name "contoso-identity" \
--display-name "Identity" --parent "contoso-platform"
az account management-group create --name "contoso-management" \
--display-name "Management" --parent "contoso-platform"
az account management-group create --name "contoso-connectivity" \
--display-name "Connectivity" --parent "contoso-platform"

# Landing zone management groups
az account management-group create --name "contoso-landingzones" \
--display-name "Landing Zones" --parent "contoso"
az account management-group create --name "contoso-prod" \
--display-name "Production" --parent "contoso-landingzones"
az account management-group create --name "contoso-nonprod" \
--display-name "Non-Production" --parent "contoso-landingzones"

# Sandbox and decommissioned
az account management-group create --name "contoso-sandbox" \
--display-name "Sandbox" --parent "contoso"
az account management-group create --name "contoso-decommissioned" \
--display-name "Decommissioned" --parent "contoso"

Platform vs Application Landing Zones

Platform landing zones host shared infrastructure — networking hubs, DNS, identity services, monitoring, and security tools. These are managed by the central platform team.

Application landing zones are where business workloads live. Each application team gets a subscription (or set of subscriptions) under the Landing Zones management group with inherited policies and connectivity already wired up.

# Move a new subscription into the Production landing zone
az account management-group subscription add \
--name "contoso-prod" \
--subscription "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

# Verify the subscription placement
az account management-group show \
--name "contoso-prod" \
--expand \
--recurse \
--query "children[?type=='Microsoft.Management/managementGroups/subscriptions'].displayName"

The Connectivity Subscription — Hub-Spoke Networking

The connectivity subscription is the nerve center of your network. It hosts the hub VNet, Azure Firewall (or third-party NVA), VPN/ExpressRoute gateways, and DNS infrastructure.

# Create the hub VNet
az network vnet create \
--name vnet-hub-eastus \
--resource-group rg-connectivity \
--address-prefix 10.0.0.0/16 \
--subnet-name AzureFirewallSubnet \
--subnet-prefix 10.0.1.0/26

# Add a gateway subnet for VPN/ExpressRoute
az network vnet subnet create \
--vnet-name vnet-hub-eastus \
--resource-group rg-connectivity \
--name GatewaySubnet \
--address-prefix 10.0.2.0/27

# Deploy Azure Firewall
az network firewall create \
--name fw-hub-eastus \
--resource-group rg-connectivity \
--location eastus \
--tier Premium \
--threat-intel-mode Deny

# Create a spoke VNet and peer it to the hub
az network vnet create \
--name vnet-spoke-app1 \
--resource-group rg-app1-networking \
--address-prefix 10.1.0.0/16

az network vnet peering create \
--name hub-to-spoke-app1 \
--resource-group rg-connectivity \
--vnet-name vnet-hub-eastus \
--remote-vnet "/subscriptions/<sub-id>/resourceGroups/rg-app1-networking/providers/Microsoft.Network/virtualNetworks/vnet-spoke-app1" \
--allow-vnet-access \
--allow-forwarded-traffic \
--allow-gateway-transit

The hub-spoke topology ensures all traffic flows through a single inspection point. Spoke VNets cannot communicate directly with each other — they must route through the hub firewall.

Identity and Management Subscriptions

The identity subscription hosts Active Directory Domain Controllers, Microsoft Entra Connect servers, and certificate authorities. Keeping these in their own subscription isolates credential infrastructure from application workloads.

The management subscription hosts:

  • Log Analytics workspace — centralized logging for all subscriptions
  • Azure Monitor — metrics, alerts, dashboards
  • Microsoft Sentinel — SIEM and SOAR
  • Azure Automation — patching, configuration, runbooks
# Create a central Log Analytics workspace
az monitor log-analytics workspace create \
--workspace-name law-central-eastus \
--resource-group rg-management \
--location eastus \
--retention-time 90 \
--sku PerGB2018

# Enable Diagnostic Settings for a subscription
az monitor diagnostic-settings subscription create \
--name "send-to-central-law" \
--location eastus \
--workspace "/subscriptions/<mgmt-sub>/resourceGroups/rg-management/providers/Microsoft.OperationalInsights/workspaces/law-central-eastus" \
--logs '[{"category":"Administrative","enabled":true},{"category":"Security","enabled":true},{"category":"Policy","enabled":true}]'

Policy-Driven Governance

Policies assigned at the management group level cascade to every subscription and resource beneath. This is how you enforce security baselines without manually auditing each team.

# Deny public IP creation in production landing zones
az policy assignment create \
--name "deny-public-ip-prod" \
--display-name "Deny Public IP in Production" \
--scope "/providers/Microsoft.Management/managementGroups/contoso-prod" \
--policy "/providers/Microsoft.Authorization/policyDefinitions/83a86a26-fd1f-447c-b59d-e51f44264114"

# Require tags on all resource groups
az policy assignment create \
--name "require-cost-center-tag" \
--display-name "Require CostCenter Tag" \
--scope "/providers/Microsoft.Management/managementGroups/contoso-landingzones" \
--policy "/providers/Microsoft.Authorization/policyDefinitions/96670d01-0a4d-4649-9c89-2d3abc0a5025" \
--params '{"tagName": {"value": "CostCenter"}}'

# Audit resources without diagnostic settings
az policy assignment create \
--name "audit-diag-settings" \
--display-name "Audit Missing Diagnostic Settings" \
--scope "/providers/Microsoft.Management/managementGroups/contoso" \
--policy "/providers/Microsoft.Authorization/policyDefinitions/7f89b1eb-583c-429a-8828-af049802c1d9"

Key policies for enterprise landing zones:

PolicyScopeEffect
Deny public IPProductionDeny
Require encryption at restLanding ZonesDeny
Allowed regions (eastus, westus2)Organization rootDeny
Require resource tagsLanding ZonesDeny
Enable Defender for CloudOrganization rootDeployIfNotExists
Audit NSG flow logsConnectivityAudit

Deploying with Bicep

The Azure Landing Zone Accelerator provides production-ready Bicep modules. Here is a simplified module for deploying a management group hierarchy:

targetScope = 'tenant'

@description('The top-level management group name')
param topLevelMgName string = 'contoso'

var managementGroups = [
{ name: '${topLevelMgName}-platform', displayName: 'Platform', parent: topLevelMgName }
{ name: '${topLevelMgName}-identity', displayName: 'Identity', parent: '${topLevelMgName}-platform' }
{ name: '${topLevelMgName}-management', displayName: 'Management', parent: '${topLevelMgName}-platform' }
{ name: '${topLevelMgName}-connectivity', displayName: 'Connectivity', parent: '${topLevelMgName}-platform' }
{ name: '${topLevelMgName}-landingzones', displayName: 'Landing Zones', parent: topLevelMgName }
{ name: '${topLevelMgName}-prod', displayName: 'Production', parent: '${topLevelMgName}-landingzones' }
{ name: '${topLevelMgName}-nonprod', displayName: 'Non-Production', parent: '${topLevelMgName}-landingzones' }
{ name: '${topLevelMgName}-sandbox', displayName: 'Sandbox', parent: topLevelMgName }
{ name: '${topLevelMgName}-decommissioned', displayName: 'Decommissioned', parent: topLevelMgName }
]

resource topLevelMg 'Microsoft.Management/managementGroups@2023-04-01' = {
name: topLevelMgName
properties: {
displayName: 'Contoso Organization'
}
}

@batchSize(1)
resource mgs 'Microsoft.Management/managementGroups@2023-04-01' = [for mg in managementGroups: {
name: mg.name
properties: {
displayName: mg.displayName
details: {
parent: {
id: tenantResourceId('Microsoft.Management/managementGroups', mg.parent)
}
}
}
dependsOn: [topLevelMg]
}]

Deploy it:

az deployment tenant create \
--name "deploy-mg-hierarchy" \
--location eastus \
--template-file management-groups.bicep \
--parameters topLevelMgName="contoso"

Reference Architecture Checklist

Before going live, validate these items:

  1. Management groups created with correct parent-child relationships
  2. Subscriptions placed under the correct management groups
  3. Hub VNet deployed with firewall, gateway, and bastion subnets
  4. Spoke peerings configured with gateway transit enabled
  5. Azure Firewall rules allowing required traffic, denying everything else
  6. Central Log Analytics workspace receiving logs from all subscriptions
  7. Azure Policy assignments enforcing tagging, encryption, allowed regions, and Defender
  8. RBAC roles assigned at management group scope (Platform team as Owner of Platform, App teams as Contributor of their subscriptions)
  9. DNS private zones linked to hub VNet, conditional forwarding configured
  10. Budget alerts configured on every subscription

Landing zones are not a one-time deployment. They evolve as your organization grows. Start with the reference architecture, customize the policies and network topology to your needs, and treat the entire configuration as code in a Git repository. When the next 200 workloads arrive, they will land on solid ground.