Skip to content

Azure Networking Basics

Key Points

  • VNet is your private IP space in Azure. Plan CIDR generously — every team underestimates and runs out of /24s within 18 months.
  • NSG is a stateful 5-tuple packet filter (src/dst IP, src/dst port, protocol). Rules ordered by priority (lower = higher); first match wins.
  • Service Endpoints vs Private Endpoints: SE keeps traffic on Azure backbone but the resource still has a public DNS name; PE puts an actual private IP inside your VNet (preferred for security).
  • Hub-and-spoke is the default enterprise topology. Hub holds firewall, gateway, DNS; spokes peer to hub. Peering is non-transitive — spoke A cannot reach spoke B without UDR + NVA.
  • Application Gateway (regional L7), Front Door (global L7), Load Balancer (L4) — three different jobs; pick by scope and protocol layer.

Concepts (deep dive)

VNet & subnets

A Virtual Network (VNet) is a logical isolation boundary in Azure: an RFC1918 address space (10.0.0.0/16, 192.168.0.0/16, 172.16.0.0/12) carved into subnets. Every NIC, App Service Plan with VNet integration, AKS node pool, Container App environment, etc. consumes IPs from a subnet.

VNet 10.0.0.0/16
 ├─ snet-app    10.0.1.0/24   (App Service / AKS)
 ├─ snet-data   10.0.2.0/24   (SQL / Cosmos PE)
 ├─ snet-pe     10.0.3.0/24   (Private Endpoints)
 ├─ snet-agw    10.0.4.0/24   (App Gateway — dedicated)
 └─ GatewaySubnet 10.0.255.0/27  (must be named exactly this)

⚠️ Plan generously. AKS reserves IPs aggressively (especially Azure CNI). App Service VNet integration consumes a /26 minimum. PE-heavy environments can burn a /24 per dozen services. Once a VNet exists you cannot easily shrink/grow it — you can add address space but rebuilding peerings is painful.

💡 Reserved subnet names: GatewaySubnet, AzureFirewallSubnet, AzureBastionSubnet, RouteServerSubnet. Azure reserves the first 4 and last 1 IPs of every subnet (so a /29 gives you 3 usable hosts, not 8).

NSG (Network Security Group)

Priority  Name                Source       Dst        Port   Action
100       AllowVnetIn         VirtualNetwork  *       *      Allow
110       AllowAzureLBIn      AzureLoadBalancer *     *      Allow
4096      DenyAllInbound      *            *          *      Deny
  • Stateful: outbound flow auto-allows the return; you don't need a mirror inbound rule.
  • Priority 100–4096; lower number wins.
  • Default rules (65000+) cannot be deleted: AllowVnetInBound, AllowAzureLoadBalancerInBound, DenyAllInBound.
  • Apply to subnet (preferred) or NIC — both apply, both must allow.

ASG (Application Security Group)

Tag-like grouping of NICs. NSG rules reference ASGs instead of CIDRs:

Allow tcp 443 from ASG:web-tier to ASG:api-tier

Add/remove a VM from an ASG and policy follows it. Avoid hard-coding IPs in NSG rules.

Service Endpoints vs Private Endpoints

                 Service Endpoint                  Private Endpoint
                ┌──────────────────┐              ┌──────────────────┐
   Your VNet ───┤ optimized route  ├── Azure ─────┤ private IP in    │
                │ over backbone    │   service    │ your subnet      │
                └──────────────────┘              └──────────────────┘
   DNS:  myacct.blob.core.windows.net             same name → resolves
         (still public name)                      to 10.x via Private DNS
   Identity: VNet identity passed in              Resource has a real
             "VirtualNetwork" allowlist           private NIC; firewall off
   Cross-tenant: ❌                               ✅
   Cross-region: ❌                               ✅ via Global Peering
   Cost:    free                                  $7/mo + $0.01/GB

Private Endpoints are the modern default for prod. Service Endpoints are cheaper and fine for dev or non-sensitive workloads, but they don't truly isolate the resource — it still has a reachable public DNS name (just firewalled).

Hub-and-spoke topology

              ┌──────────────────────────┐
              │       Hub VNet           │
              │  ┌──────┐  ┌──────────┐  │
              │  │ FW   │  │ ER/VPN GW│  │
              │  └──────┘  └──────────┘  │
              │  ┌─────────────────────┐ │
              │  │ Private DNS Zones   │ │
              │  └─────────────────────┘ │
              └──────┬──────────┬────────┘
                     │ peer     │ peer
              ┌──────▼───┐  ┌───▼──────┐
              │ Spoke A  │  │ Spoke B  │
              │ (prod)   │  │ (nonprod)│
              └──────────┘  └──────────┘
  • Hub: shared services (firewall, gateway, DNS, Bastion, monitoring).
  • Spokes: workload VNets, isolated by environment / business unit.
  • Peering is non-transitive: spoke A → hub → spoke B requires UDRs forcing spoke A traffic through the hub firewall, which then routes to spoke B.

Virtual WAN

Managed multi-region hub-and-spoke. Microsoft runs the hubs; you attach spokes, branches (S2S), and users (P2S). For multi-region enterprises this beats hand-rolling peerings.

DNS in Azure

Three resolvers in play:

  1. Azure-provided DNS (168.63.129.16) — resolves public Azure names + VNet name resolution for VMs in the same VNet.
  2. Private DNS Zones — your own zone (e.g., privatelink.blob.core.windows.net) linked to one or more VNets; PEs auto-register A records here.
  3. DNS Private Resolver — for hybrid: forward queries between on-prem DNS and Azure Private DNS without running a custom DNS VM.

⚠️ Common loop: hub DNS forwards to on-prem; on-prem forwards Azure suffixes back to hub. Bad config = stack overflow / SERVFAIL.

ExpressRoute

Private circuit between your DC and Azure (delivered by carrier or "Direct" port pair). No traffic touches the public internet.

  • Provider model: Equinix, Megaport, AT&T, etc. provision a virtual circuit.
  • ExpressRoute Direct: 10/100 Gbps port pairs into Microsoft Edge — for hyperscale customers.
  • Sovereign circuits: Gov, secret cloud variants.
  • Peering types: Private (your VNets), Microsoft (Azure PaaS over private), public peering deprecated.

VPN Gateway

Cheaper than ER. Two modes: - Site-to-Site (S2S): IPsec tunnel from on-prem firewall to Azure VPN GW. - Point-to-Site (P2S): laptops/devs connect via OpenVPN/IKEv2; AAD or cert-based auth.

Application Gateway vs Front Door vs Load Balancer

Layer Scope Use
Azure Load Balancer L4 (TCP/UDP) Regional Internal LB for VMs/AKS; outbound NAT
Application Gateway L7 (HTTP/S) Regional WAF, path-based routing inside one region
Front Door L7 (HTTP/S) Global anycast Global edge entry, WAF, multi-region failover, caching
Traffic Manager DNS Global DNS-level steering (no proxy); for non-HTTP or App Service multi-region

💡 Common combo: Front Door → App Gateway → AKS internal LB. Front Door for global edge + WAF; App Gateway for regional L7; internal LB for service mesh ingress.

Bastion

Browser-based RDP/SSH to private VMs without exposing public IPs or opening 3389/22. Bastion Standard supports IP-based connections, native client, and shareable links. Pricey (~$150/mo idle) but eliminates jumpbox sprawl.

NAT Gateway

Outbound-only static IP for a subnet. Solves SNAT port exhaustion — the silent killer of App Service / AKS workloads making thousands of outbound HTTPS calls. Default Azure SNAT is shared and limited; NAT Gateway gives you 64K ports per assigned IP.

UDR (User-Defined Routes)

Override Azure's default system routes. Common: force all 0.0.0.0/0 from a subnet through Azure Firewall (forced tunneling).

0.0.0.0/0  →  10.0.0.4 (Azure Firewall)

⚠️ Forgetting a UDR is the #1 reason "my private endpoint can't reach Storage" — traffic exits to the internet, hits firewall, gets dropped.

Bicep: VNet + subnet + NSG

param location string = resourceGroup().location

resource nsg 'Microsoft.Network/networkSecurityGroups@2024-01-01' = {
  name: 'nsg-app'
  location: location
  properties: {
    securityRules: [
      {
        name: 'AllowHttpsInbound'
        properties: {
          priority: 100
          direction: 'Inbound'
          access: 'Allow'
          protocol: 'Tcp'
          sourceAddressPrefix: '*'
          sourcePortRange: '*'
          destinationAddressPrefix: '*'
          destinationPortRange: '443'
        }
      }
    ]
  }
}

resource vnet 'Microsoft.Network/virtualNetworks@2024-01-01' = {
  name: 'vnet-prod'
  location: location
  properties: {
    addressSpace: { addressPrefixes: [ '10.0.0.0/16' ] }
    subnets: [
      {
        name: 'snet-app'
        properties: {
          addressPrefix: '10.0.1.0/24'
          networkSecurityGroup: { id: nsg.id }
          privateEndpointNetworkPolicies: 'Disabled'
        }
      }
    ]
  }
}

How it works under the hood

  • Every VM/NIC traffic flows through the Azure SDN (software-defined networking) layer; NSG rules are enforced at the host hypervisor, not as a separate appliance.
  • VFP (Virtual Filtering Platform) evaluates NSG/ASG rules per packet flow. First packet of a flow → match rules; rest of the flow uses cached decision (the "stateful" part).
  • VNet peering programs the SDN with routes; throughput is line rate (no gateway in the path). Cross-region peering goes over Microsoft's global backbone.
  • Private Endpoint creates an actual NIC + private IP. DNS resolution to that PE goes through a Private DNS Zone (e.g., privatelink.blob.core.windows.net) linked to your VNet.
  • 168.63.129.16 is the magic Azure host IP — provides DHCP, DNS, health probes, instance metadata. Never block it in NSG/firewall or VMs lose touch with the platform.
   Client ─► VFP (NSG eval) ─► VNet routing ─► Peering / GW / Internet
                └──► flow cache (first match decision)

Code: correct vs wrong

❌ Wrong: NSG with public access "for testing"

Allow tcp 22 from * to 10.0.1.0/24

Brute force bots find it within hours.

✅ Correct: scope source

Allow tcp 22 from VirtualNetwork to AsgManagement
Allow tcp 22 from CorporateIpRange to AsgManagement

Even better: use Bastion and remove inbound 22/3389 entirely.

❌ Wrong: NSG blocking 168.63.129.16

Deny outbound * → 168.63.129.16

Breaks DHCP, health probes, AKS extensions, instance metadata.

✅ Correct: leave Azure platform addresses alone

Use the AzurePlatformDNS, AzurePlatformIMDS service tags if you must control them, and explicitly allow.

❌ Wrong: PE without Private DNS Zone

// Created PE but didn't link the privatelink.* DNS zone

Client resolves myacct.blob.core.windows.net → public IP → hits firewall → fails.

resource zone 'Microsoft.Network/privateDnsZones@2024-06-01' = {
  name: 'privatelink.blob.core.windows.net'
  location: 'global'
}
resource link 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2024-06-01' = {
  parent: zone
  name: 'vnet-prod-link'
  location: 'global'
  properties: {
    registrationEnabled: false
    virtualNetwork: { id: vnet.id }
  }
}

Design patterns for this topic

Pattern 1 — "Hub-and-spoke with shared firewall"

  • Intent: centralize egress, DNS, and policy enforcement across many workloads.

Pattern 2 — "Private Endpoints for all PaaS"

  • Intent: eliminate public exposure of Storage/SQL/Cosmos/Key Vault.

Pattern 3 — "ASG-based segmentation"

  • Intent: rules reference roles (web/api/data) not IP ranges; survives reorganization.

Pattern 4 — "NAT Gateway for outbound SNAT"

  • Intent: prevent port exhaustion under high outbound concurrency.

Pattern 5 — "Front Door + regional App Gateway"

  • Intent: global edge + WAF; regional L7 routing into AKS / App Service.

Pros & cons / trade-offs

Aspect Pros Cons
Hub-and-spoke Centralized policy, cost-share Hub becomes SPOF if not zone-redundant
Private Endpoints True isolation; cross-tenant $7/mo each + DNS complexity
Service Endpoints Free; simple Resource still has public DNS
App Gateway Managed WAF, regional $150+/mo idle
Front Door Global anycast, edge cache No raw TCP; cost at scale
NAT Gateway Solves SNAT exhaustion $32/mo + per-GB processing
ExpressRoute Private, predictable Months to provision; expensive
VPN Gateway Days to set up Lower bandwidth, internet path

When to use / when to avoid

  • Use Private Endpoints for production PaaS — the security baseline expectation.
  • Use hub-and-spoke as soon as you have >2 workload VNets.
  • Use NAT Gateway if your app makes thousands of concurrent outbound HTTPS calls.
  • Use Front Door + App Gateway combo for global multi-region public APIs.
  • Avoid building NSGs with /32 IP rules — use ASGs and service tags.
  • Avoid ExpressRoute for small workloads — VPN GW is fine until ~5 Gbps or compliance demands it.

Interview Q&A

Q1. VNet peering transitivity? Non-transitive by default. A↔Hub and B↔Hub does not give you A↔B. Use UDRs through an NVA, or Virtual WAN.

Q2. Service Endpoint vs Private Endpoint? SE: optimized route, resource keeps public name + firewall allowlist. PE: real private NIC in your subnet; truly isolated; supports cross-tenant/region.

Q3. NSG default rules? AllowVnetInBound, AllowAzureLoadBalancerInBound, DenyAllInBound at priority 65000+ — can't delete, can override with lower priority.

Q4. ASG benefit? Reference roles instead of IPs. NICs move; rules follow.

Q5. App Gateway vs Front Door? App Gateway: regional L7, WAF, path/header routing. Front Door: global anycast L7, edge cache, multi-region failover.

Q6. Why NAT Gateway? Solves SNAT port exhaustion for high outbound concurrency. Provides static egress IP per subnet.

Q7. What's 168.63.129.16? Azure host magic IP — DHCP, DNS, health probes, IMDS. Never block.

Q8. Bastion? Browser RDP/SSH to private VMs without public IPs or open 22/3389.

Q9. UDR forced tunneling? Override default route to force all egress through firewall/NVA.

Q10. ExpressRoute vs VPN GW? ER: private circuit, predictable bandwidth, no internet. VPN: IPsec over internet, cheaper, lower SLA.

Q11. GatewaySubnet name requirement? Yes — must be exactly GatewaySubnet. Same for AzureFirewallSubnet, AzureBastionSubnet.

Q12. Why PE needs Private DNS Zone? The PE has a private IP, but the FQDN still resolves publicly unless the privatelink.* zone is linked to your VNet, overriding resolution.


Gotchas / common mistakes

  • ⚠️ CIDR too small/24 looks big until AKS + App Service integration eats it.
  • ⚠️ Missing UDR — PE traffic exits to internet because firewall route isn't applied.
  • ⚠️ Blocking 168.63.129.16 — breaks DHCP, IMDS, platform health.
  • ⚠️ PE without Private DNS Zone — resolves to public IP, firewall drops.
  • ⚠️ Peering non-transitivity surprise — spoke-to-spoke needs explicit routing.
  • ⚠️ NSG rule priority confusion — lower number = higher priority. First match wins.
  • ⚠️ SNAT port exhaustion — silent connection failures from App Service under load. Add NAT Gateway.
  • ⚠️ DNS forwarding loops — hub forwards to on-prem, on-prem forwards back.

Further reading