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:
| Tag | Represents |
|---|---|
Internet | All public internet traffic |
VirtualNetwork | VNet address space + peered VNets |
AzureLoadBalancer | Azure infrastructure health probes |
Storage | Azure Storage IP ranges |
Sql | Azure SQL IP ranges |
AzureCloud | All Azure datacenter IPs |
AppService | App 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).
| SKU | Public | Internal | Availability Zones | Use Case |
|---|---|---|---|---|
| Basic | ✓ | ✓ | No | Dev/test |
| Standard | ✓ | ✓ | Yes | Production |
# 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
| Feature | Load Balancer | App Gateway | Front Door |
|---|---|---|---|
| Layer | 4 (TCP/UDP) | 7 (HTTP/HTTPS) | 7 (HTTP/HTTPS) |
| Scope | Regional | Regional | Global |
| URL routing | No | Yes | Yes |
| WAF | No | Yes (WAF_v2) | Yes |
| SSL offload | No | Yes | Yes |
| CDN | No | No | Yes |
| Multi-region | No | No | Yes |
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-and-Spoke (Recommended for Enterprise)
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
- Segment by tier: Separate subnets for web, application, and database layers
- Use NSGs everywhere: Apply to subnets, not individual NICs, for manageability
- Avoid public IPs on VMs: Use Bastion for management access
- Use Private Endpoints: Keep traffic to Azure services inside the VNet
- Plan CIDR ranges carefully: Avoid overlap with on-premises ranges; leave room to grow
- 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.