← Back to Index
↳ Project /23Azure · Platform · Governance

Azure Landing Zone

The governance foundation a workload subscription inherits before anyone deploys into it: a management group hierarchy, policy as code, and a hub-spoke network whose spokes are vended by a single module call.

Role
Cloud / Platform
Cloud
Azure
Hierarchy
4 levels
Resources
24 (Terraform)
Tenant Root
mg-jordann6
Workloads MG
subscription placed
Azure Policy
owner tag · no public IP
Hub VNet
10.0.0.0/16
Reserved
Firewall · Gateway · Bastion
snet-management
NSG denies inbound
Platform Spoke
10.1.0.0/16 · peered
Sandbox Spoke
10.2.0.0/16 · peered
Governance attaches to the management group before the first subscription lands, so policy is the environment rather than a ticket

/01Problem

Governance applied after workloads exist is negotiation. Governance applied to a management group before the first subscription lands there is just the environment. The distinction decides whether a policy is a guardrail or a ticket.

The goal was the smallest complete Azure foundation that a workload subscription could be dropped into and immediately inherit: a hierarchy that policy can attach to, a network with room for the services it will eventually need, and a repeatable way to add the next spoke.

/02Approach

  • A four-level management group tree under the tenant root, splitting Platform, Workloads, and Sandbox, with the subscription moved into Workloads so all policy assignments apply to everything in it automatically.
  • Three custom Azure Policy definitions authored and assigned at the Workloads scope: require an owner tag, deny public IP creation, and restrict resources to allowed locations.
  • A hub VNet at 10.0.0.0/16 carrying reserved subnets for Firewall, Gateway, and Bastion alongside an active management subnet whose NSG blocks inbound internet.
  • Two spokes, Platform and Sandbox, each peered bidirectionally with the hub, provisioned through a reusable module so a third spoke is one block.

/03Architecture

The reserved subnets are the detail that matters most and costs nothing. Azure Firewall, VPN and ExpressRoute Gateway, and Bastion each require an exactly-named subnet at a minimum prefix size, so those subnets are carved and named correctly up front even though none of the services are deployed. Activating any of them later is a resource addition rather than a re-addressing exercise across every peered network, which is the expensive version of that mistake.

Policy effects are set to Audit for the demo deployment rather than Deny. That is a deliberate choice worth stating plainly: in a production pipeline these become Deny and run as a separate governance stage ahead of workload provisioning, but a Deny effect in a demo environment blocks the very resources the demo needs to create.

/04Outcome

Deployed against a real Azure tenant and verified through the control plane rather than the plan file: the management group hierarchy, the subscription's placement under Workloads, the policy assignments at that scope, and both peering directions reporting Connected.

Then destroyed clean, with the subscription automatically re-associating to the tenant root group. The whole environment carries no VMs, no Firewall, no Bastion, and no Gateway, so the cost of standing it up and tearing it down repeatedly is effectively nothing, which is what makes it usable as a reference rather than a one-time demo.

↳ Run Receipt/23
Provision24 Terraform resources: 4-level management group tree, 3 policy definitions and assignments, hub plus 2 peered spokes
VerifyHierarchy, subscription placement, policy assignments, and both peering directions confirmed via the Azure control plane
DestroyTorn down clean; subscription auto-reassociated to the tenant root group
Costeffectively zero, no VMs, Firewall, Bastion, or Gateway
Azure Management GroupsAzure PolicyHub-Spoke VNetVNet PeeringNSGTerraform
StatusCheckingDeployed2026-08-03 18:28 UTCVisitsOriginPrivate S3 + CloudFront OACPipelineGitHub Actions OIDCCounterAPI Gateway + Lambda + DynamoDB