1. Address Space Planning at Scale
🔑 RFC 1918 Ranges & Their Practical Limits
Azure VNets use RFC 1918 private addresses. Your choice of range determines maximum scale:
- 10.0.0.0/8 — 16.7M addresses. Use this as your enterprise super-block. Partition it across regions and environments.
- 172.16.0.0/12 — 1M addresses. Often reserved for on-premises legacy or DMZs.
- 192.168.0.0/16 — 65K addresses. Too small for cloud-scale; avoid for Azure (conflicts with home networks and VPN clients).
CIDR Sizing Rules of Thumb
- Azure reserves 5 IPs per subnet (first 4 + last). A /28 gives only 11 usable hosts.
- Always size subnets 2× current need — you cannot resize a subnet with resources in it.
- VNet address space can be expanded without downtime, but overlapping with a peered VNet requires deleting the peering first.
- Document a CIDR allocation table (IPAM) before deploying anything. Tools: Azure IPAM, Excel, or NetBox.
Avoiding Overlaps with On-Premises
- Inventory all on-prem ranges (including forgotten labs, DR sites, partner VPNs).
- Reserve a dedicated slice of 10.x.x.x for Azure (e.g., 10.64.0.0/10 → 4M addresses for cloud).
- Use supernetting: summarize Azure ranges into a single route advertisement back to on-prem.
2. Hub-Spoke: Address Allocation Strategy
🔑 Allocate Big for Hub, Moderate for Spokes, Reserve for Growth
A proven pattern for enterprise networks:
- Hub VNet: /16 (65K IPs) — holds gateway, firewall, bastion, DNS, shared services.
- Each Spoke VNet: /20 (4K IPs) — enough for multiple subnets within a workload.
- Growth Reserve: Leave 50% of your super-block unallocated for future spokes/regions.
Example: Regional Allocation from 10.64.0.0/10
| Component | CIDR | Usable IPs | Purpose |
|---|---|---|---|
| East US Hub | 10.64.0.0/16 | ~65K | Shared services, gateways, firewall |
| Spoke 01 (ERP) | 10.65.0.0/20 | ~4K | SAP/ERP workload |
| Spoke 02 (Web) | 10.65.16.0/20 | ~4K | Public-facing web apps |
| Spoke 03 (Data) | 10.65.32.0/20 | ~4K | Data platform (SQL, Synapse) |
| Reserved | 10.65.48.0/20 – 10.65.240.0/20 | — | Future spokes (12+ slots) |
| West Europe Hub | 10.68.0.0/16 | ~65K | Second region hub |
Hub-spoke CIDR allocation: non-overlapping /20 spokes carved from a regional /14 super-block, with growth reserves.
3. Subnet Design Patterns
🔑 Purpose-Built Subnets with Specific Naming
Azure requires certain subnet names for platform services. Design subnets by function, not by team:
Hub Subnet Layout
| Subnet Name | CIDR (from hub /16) | Purpose | Required Name? |
|---|---|---|---|
| GatewaySubnet | 10.64.0.0/26 | VPN/ER Gateway | ✅ Exact name required |
| AzureFirewallSubnet | 10.64.1.0/26 | Azure Firewall | ✅ Exact name required |
| AzureFirewallManagementSubnet | 10.64.1.64/26 | Firewall forced-tunnel mgmt | ✅ If forced tunneling |
| AzureBastionSubnet | 10.64.2.0/26 | Azure Bastion | ✅ Exact name required |
| snet-dns-resolver-inbound | 10.64.3.0/28 | DNS Private Resolver inbound | ❌ Custom, delegated |
| snet-dns-resolver-outbound | 10.64.3.16/28 | DNS Private Resolver outbound | ❌ Custom, delegated |
| snet-shared-services | 10.64.4.0/24 | DCs, SCCM, monitoring agents | ❌ |
Spoke Subnet Layout (Typical 3-Tier App)
Spoke subnet layout: separate subnets for each tier, private endpoints, and delegated subnets — each with its own NSG.
Subnet Design Principles
- One NSG per subnet — don't share NSGs across subnets with different security postures.
- Separate private-endpoint subnet — keeps PE NICs isolated; easier to audit and avoids NSG conflicts.
- Delegation subnets are exclusive — no other resources can be placed in a delegated subnet.
- /27 minimum for most services — gives 27 usable IPs; enough for auto-scale.
- GatewaySubnet: /27 minimum (Microsoft recommends /26 for ExpressRoute coexistence).
4. Subnet Delegation for PaaS
🔑 Delegation = Exclusive Access for a PaaS Service
When you delegate a subnet, Azure grants the specified service permission to inject resources (NICs, load balancers) into that subnet. No other resource types can coexist. The service may also apply its own network policies.
Common Delegations
| Service | Delegation Namespace | Min Subnet Size | Key Constraints |
|---|---|---|---|
| App Service (VNet Integration) | Microsoft.Web/serverFarms | /28 | One plan per subnet; use separate subnet per ASP |
| SQL Managed Instance | Microsoft.Sql/managedInstances | /27 (16 instances max) | Subnet dedicated; requires route table and NSG with specific rules |
| Container Apps Environment | Microsoft.App/environments | /23 | Large CIDR required; 250+ IPs for infrastructure |
| Azure NetApp Files | Microsoft.NetApp/volumes | /28 | Dedicated subnet; no NSGs supported |
| Azure Databricks | Microsoft.Databricks/workspaces | /26 (two subnets) | Needs host + container subnets |
| API Management (stv2) | Microsoft.ApiManagement/service | /27 | NSG required with specific ports open |
- Delegation (VNet Integration): The PaaS service makes outbound calls from your VNet (e.g., App Service calling SQL via private IP). The service injects into your subnet.
- Private Endpoints: You access a PaaS service inbound via a private IP in your VNet. A NIC is created in your subnet representing the PaaS resource.
- Both together: App Service uses delegation for outbound VNet integration AND a Private Endpoint on Storage for inbound private access to blobs.
5. DNS Architecture: Private Resolver & Conditional Forwarding
🔑 Azure DNS Private Resolver Eliminates Custom DNS VMs
Before Private Resolver, you needed IaaS DNS forwarders (BIND/Windows DNS VMs) in the hub to resolve private DNS zones from on-premises. Private Resolver is a managed service that handles inbound (on-prem → Azure) and outbound (Azure → on-prem) DNS forwarding natively.
Placement: Hub vs Spoke
| Aspect | Resolver in Hub (Recommended) | Resolver in Each Spoke |
|---|---|---|
| Cost | 1 resolver shared across all spokes | N resolvers — expensive |
| Management | Centralized ruleset & forwarding rules | Duplicate config per spoke |
| On-prem forwarding | Single inbound endpoint IP for on-prem DNS to target | Multiple IPs to manage |
| Latency | +1 hop through peering (negligible for DNS) | Local resolution |
| Failure blast radius | Hub outage affects all DNS | Isolated per spoke |
| Best for | Most enterprises (centralized governance) | Highly isolated workloads (regulated) |
Architecture Pattern
- Inbound endpoint (in hub subnet): On-prem DNS servers conditionally forward
*.privatelink.database.windows.netetc. to this IP. - Outbound endpoint (in hub subnet): Azure VMs forward queries for on-prem zones (e.g.,
corp.contoso.com) through this endpoint → on-prem DNS. - DNS Forwarding Ruleset: Linked to spoke VNets via VNet links. Rules define which domains go where.
- Private DNS Zones: Linked to hub VNet; spokes resolve via the resolver (not direct zone links to every spoke).
# Forwarding Ruleset attached to all spoke VNets
Rule 1: *.blob.core.windows.net → Azure DNS (168.63.129.16)
Rule 2: *.database.windows.net → Azure DNS (168.63.129.16)
Rule 3: corp.contoso.com → On-prem DNS (172.16.1.10, 172.16.1.11)
Rule 4: legacy.internal → On-prem DNS (172.16.1.10)
Default: all other queries → Azure DNS (168.63.129.16)
6. Real-World: Planning Network for 50-App Migration with Hybrid
Scenario
Contoso is migrating 50 applications from two on-premises data centers to Azure (East US primary, West Europe DR). On-prem uses 172.16.0.0/12. They need hub-spoke, hybrid connectivity via ExpressRoute, and private access to PaaS services.
The Design
- IPAM allocation: Reserve 10.64.0.0/10 for Azure (~4M IPs). East US gets 10.64.0.0/12, West Europe gets 10.80.0.0/12.
- Hub sizing: Each regional hub = /16 (10.64.0.0/16 East, 10.80.0.0/16 West). Contains GatewaySubnet, AzureFirewallSubnet, BastionSubnet, DNS resolver subnets, and shared services.
- Spoke allocation: 50 apps grouped into ~15 spokes by business unit (3–4 apps per spoke). Each spoke = /20 (4K IPs). Leaves room for 40+ future spokes per region.
- Subnet template per spoke: snet-web /24, snet-app /24, snet-data /24, snet-pe /24, snet-delegation /24, reserved /24 ×11.
- DNS: Private Resolver in each hub. On-prem DNS forwards privatelink zones to hub inbound endpoint. Outbound rules forward corp.contoso.com to on-prem DCs.
- Delegation: 12 apps use App Service → each gets a delegated /27 subnet for VNet integration. 2 SQL MI instances → dedicated /27 delegated subnets in their respective spokes.
- Growth: 50% of each regional /12 block remains unallocated. New spokes follow the template without renumbering.
Key Decisions
- Used /20 per spoke (not /24) even though most apps need <100 IPs — future delegation subnets and PE subnets consume space fast.
- Centralized all private DNS zone links at the hub level — avoids managing 50+ zone links per spoke.
- Documented the CIDR plan in a shared IPAM tool with approval workflow for new allocations.
Summary
- Use 10.x.x.x/8 as your cloud super-block; partition by region and environment to avoid overlaps.
- Hub = /16, Spokes = /20, always reserve 50% for growth.
- Name subnets by function; use required names (GatewaySubnet, AzureFirewallSubnet, AzureBastionSubnet) exactly.
- Delegated subnets are exclusive — size them per service requirements (Container Apps needs /23!).
- Place Azure DNS Private Resolver in the hub for centralized hybrid DNS forwarding.
- Document everything in an IPAM tool — address conflicts at scale are the #1 networking regret.