Chapter 5: Networking

Azure networking connects your resources to each other, to the internet, and to on-premises infrastructure, securely and reliably.

Virtual Network (VNet)

A Virtual Network is your private, isolated network in Azure. All resources (VMs, databases, etc.) placed in a VNet can communicate with each other privately.

VNet: 10.0.0.0/16
├── Subnet: web-snet       10.0.1.0/24   - Public-facing VMs, App Service
├── Subnet: app-snet       10.0.2.0/24   - Backend application tier
├── Subnet: db-snet        10.0.3.0/24   - Databases
└── Subnet: AzureBastionSubnet 10.0.4.0/26 - Bastion host (must use this name)

Creating a VNet

# Create VNet with an address space
az network vnet create \
  --resource-group myapp-rg \
  --name myapp-vnet \
  --address-prefix 10.0.0.0/16 \
  --location eastus

# Add subnets
az network vnet subnet create \
  --resource-group myapp-rg \
  --vnet-name myapp-vnet \
  --name web-snet \
  --address-prefix 10.0.1.0/24

az network vnet subnet create \
  --resource-group myapp-rg \
  --vnet-name myapp-vnet \
  --name db-snet \
  --address-prefix 10.0.3.0/24

# List subnets
az network vnet subnet list \
  --resource-group myapp-rg \
  --vnet-name myapp-vnet \
  --output table

VNet Peering

Connect two VNets so their resources can communicate privately (even across subscriptions or regions):

# Peer VNet A to VNet B
az network vnet peering create \
  --resource-group myapp-rg \
  --name vnetA-to-vnetB \
  --vnet-name vnetA \
  --remote-vnet /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/vnetB \
  --allow-vnet-access

# Peer VNet B to VNet A (peering is not transitive; must create both directions)
az network vnet peering create \
  --resource-group myapp-rg \
  --name vnetB-to-vnetA \
  --vnet-name vnetB \
  --remote-vnet /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/vnetA \
  --allow-vnet-access

VNet peering is not transitive: if A↔B and B↔C, then A cannot reach C unless you also peer A↔C.

Network Security Groups (NSGs)

An NSG is a stateful firewall containing allow/deny rules for inbound and outbound traffic. You attach NSGs to subnets or individual NICs.

NSG Rules (evaluated in priority order, lowest number = first)
Priority | Name          | Protocol | Source        | Destination | Port  | Action
---------|---------------|----------|---------------|-------------|-------|-------
100      | Allow-HTTP    | TCP      | Any           | Any         | 80    | Allow
110      | Allow-HTTPS   | TCP      | Any           | Any         | 443   | Allow
200      | Allow-SSH     | TCP      | 203.0.113.0/24| Any         | 22    | Allow
65000    | (default)     | Any      | VirtualNetwork| Any         | *     | Allow
65001    | (default)     | Any      | AzureLoadBal  | Any         | *     | Allow
65500    | (default)     | Any      | Any           | Any         | *     | Deny  (catch-all)
# Create an NSG
az network nsg create \
  --resource-group myapp-rg \
  --name web-nsg

# Allow HTTPS inbound
az network nsg rule create \
  --resource-group myapp-rg \
  --nsg-name web-nsg \
  --name Allow-HTTPS \
  --priority 100 \
  --direction Inbound \
  --protocol TCP \
  --source-address-prefix '*' \
  --destination-port-range 443 \
  --access Allow

# Allow SSH only from a specific IP
az network nsg rule create \
  --resource-group myapp-rg \
  --nsg-name web-nsg \
  --name Allow-SSH-Office \
  --priority 200 \
  --direction Inbound \
  --protocol TCP \
  --source-address-prefix 203.0.113.0/24 \
  --destination-port-range 22 \
  --access Allow

# Attach NSG to a subnet
az network vnet subnet update \
  --resource-group myapp-rg \
  --vnet-name myapp-vnet \
  --name web-snet \
  --network-security-group web-nsg

Service Tags

Instead of hardcoding IP ranges, use Service Tags to represent Azure services:

TagRepresents
InternetAll public internet traffic
VirtualNetworkVNet address space + peered VNets
AzureLoadBalancerAzure infrastructure health probes
StorageAzure Storage IP ranges
SqlAzure SQL IP ranges
AzureCloudAll Azure datacenter IPs
AppServiceApp Service outbound IPs
# Allow traffic only from Azure Front Door
az network nsg rule create \
  --resource-group myapp-rg \
  --nsg-name web-nsg \
  --name Allow-FrontDoor \
  --priority 150 \
  --direction Inbound \
  --protocol TCP \
  --source-address-prefix AzureFrontDoor.Backend \
  --destination-port-range 443 \
  --access Allow

Azure Bastion

Azure Bastion provides secure SSH/RDP access to VMs directly through the browser, without exposing port 22 or 3389 to the internet.

# Create Bastion (requires a /26 subnet named AzureBastionSubnet)
az network vnet subnet create \
  --resource-group myapp-rg \
  --vnet-name myapp-vnet \
  --name AzureBastionSubnet \
  --address-prefix 10.0.4.0/26

az network public-ip create \
  --resource-group myapp-rg \
  --name bastion-pip \
  --sku Standard

az network bastion create \
  --resource-group myapp-rg \
  --name myapp-bastion \
  --public-ip-address bastion-pip \
  --vnet-name myapp-vnet \
  --location eastus

Once deployed, connect to any VM via the Azure Portal → VM → Connect → Bastion.

Load Balancer

Azure Load Balancer distributes TCP/UDP traffic across healthy VMs at layer 4 (transport layer).

SKUPublicInternalAvailability ZonesUse Case
BasicNoDev/test
StandardYesProduction
# Create a public Standard Load Balancer
az network public-ip create \
  --resource-group myapp-rg \
  --name lb-pip \
  --sku Standard \
  --allocation-method Static

az network lb create \
  --resource-group myapp-rg \
  --name myapp-lb \
  --sku Standard \
  --public-ip-address lb-pip \
  --frontend-ip-name myFrontEnd \
  --backend-pool-name myBackEnd

# Health probe (TCP port 80)
az network lb probe create \
  --resource-group myapp-rg \
  --lb-name myapp-lb \
  --name httpProbe \
  --protocol Tcp \
  --port 80

# Load balancing rule (distribute port 80)
az network lb rule create \
  --resource-group myapp-rg \
  --lb-name myapp-lb \
  --name httpRule \
  --protocol Tcp \
  --frontend-port 80 \
  --backend-port 80 \
  --frontend-ip-name myFrontEnd \
  --backend-pool-name myBackEnd \
  --probe-name httpProbe

Application Gateway

Application Gateway is a layer-7 (HTTP/HTTPS) load balancer with additional features:

  • URL-based routing (/api/* to API backend, / to web backend)
  • SSL/TLS termination
  • Web Application Firewall (WAF)
  • Session affinity (cookie-based)
  • Autoscaling
# Create Application Gateway (simplified; full config has many more options)
az network application-gateway create \
  --resource-group myapp-rg \
  --name myapp-agw \
  --location eastus \
  --sku WAF_v2 \
  --capacity 2 \
  --vnet-name myapp-vnet \
  --subnet agw-snet \
  --public-ip-address agw-pip \
  --http-settings-protocol Http \
  --http-settings-port 80 \
  --routing-rule-type Basic \
  --priority 100

Application Gateway vs Load Balancer vs Front Door

FeatureLoad BalancerApp GatewayFront Door
Layer4 (TCP/UDP)7 (HTTP/HTTPS)7 (HTTP/HTTPS)
ScopeRegionalRegionalGlobal
URL routingNoYesYes
WAFNoYes (WAF_v2)Yes
SSL offloadNoYesYes
CDNNoNoYes
Multi-regionNoNoYes

Use Front Door as your global entry point for multi-region apps. Use Application Gateway for per-region routing and WAF. Use Load Balancer for non-HTTP or internal TCP traffic.

Azure DNS

Azure DNS hosts your DNS zones and records using Microsoft's global infrastructure.

# Create a DNS zone
az network dns zone create \
  --resource-group myapp-rg \
  --name myapp.com

# Add an A record
az network dns record-set a add-record \
  --resource-group myapp-rg \
  --zone-name myapp.com \
  --record-set-name www \
  --ipv4-address 20.1.2.3

# Add a CNAME
az network dns record-set cname set-record \
  --resource-group myapp-rg \
  --zone-name myapp.com \
  --record-set-name api \
  --cname myapp-api.azurewebsites.net

# List all records
az network dns record-set list \
  --resource-group myapp-rg \
  --zone-name myapp.com \
  --output table

Private DNS Zones resolve names within a VNet without going to the internet:

# Create private DNS zone
az network private-dns zone create \
  --resource-group myapp-rg \
  --name privatelink.blob.core.windows.net  # Used for Private Endpoints

# Link to a VNet
az network private-dns link vnet create \
  --resource-group myapp-rg \
  --zone-name privatelink.blob.core.windows.net \
  --name myapp-vnet-link \
  --virtual-network myapp-vnet \
  --registration-enabled false

Private Endpoints

A Private Endpoint gives an Azure service (Storage, SQL, Key Vault, etc.) a private IP address inside your VNet, so traffic never crosses the public internet.

# Get the storage account ID
STORAGE_ID=$(az storage account show \
  --name mystorageacct \
  --resource-group myapp-rg \
  --query id --output tsv)

# Create a private endpoint for Blob Storage
az network private-endpoint create \
  --resource-group myapp-rg \
  --name storage-pe \
  --vnet-name myapp-vnet \
  --subnet db-snet \
  --private-connection-resource-id $STORAGE_ID \
  --group-id blob \
  --connection-name storageConnection

VPN Gateway

VPN Gateway connects your on-premises network to an Azure VNet over an encrypted IPsec/IKE tunnel.

# Create a VPN Gateway (takes ~30 minutes)
az network vnet subnet create \
  --resource-group myapp-rg \
  --vnet-name myapp-vnet \
  --name GatewaySubnet \
  --address-prefix 10.0.5.0/27  # Must be named GatewaySubnet

az network public-ip create \
  --resource-group myapp-rg \
  --name vpn-pip \
  --allocation-method Dynamic

az network vnet-gateway create \
  --resource-group myapp-rg \
  --name myapp-vpn \
  --location eastus \
  --public-ip-address vpn-pip \
  --vnet myapp-vnet \
  --gateway-type Vpn \
  --vpn-type RouteBased \
  --sku VpnGw1

ExpressRoute is the premium alternative: a dedicated private connection from your data centre to Azure, not over the public internet. Offers guaranteed bandwidth and lower latency.

Common Network Topologies

                  Hub VNet
                  ├── Firewall / NVA
                  ├── VPN / ExpressRoute Gateway
                  └── Shared services (DNS, monitoring)
                       │
         ┌─────────────┼─────────────┐
         ▼             ▼             ▼
    Spoke VNet A   Spoke VNet B   Spoke VNet C
    (Production)   (Dev/Test)     (Data)

Use Azure Virtual WAN to manage hub-and-spoke at scale across multiple regions.

Network Architecture Best Practices

  1. Segment by tier: Separate subnets for web, application, and database layers
  2. Use NSGs everywhere: Apply to subnets, not individual NICs, for manageability
  3. Avoid public IPs on VMs: Use Bastion for management access
  4. Use Private Endpoints: Keep traffic to Azure services inside the VNet
  5. Plan CIDR ranges carefully: Avoid overlap with on-premises ranges; leave room to grow
  6. Enable NSG Flow Logs: Critical for troubleshooting and security auditing

Next Steps

Continue to 06-databases.md to learn about Azure's managed database services.