Azure Networking Best Practices: VNets, ExpressRoute, and Hub-Spoke
Master Azure networking with this practical guide. Learn VNet design, NSGs, Azure Firewall, ExpressRoute, and hub-spoke architecture with production-ready Bicep templates.
Azure Networking: Production-Ready Guide
This is Part 2 of our Cloud Networking series.
Series Navigation
Quick Start: Deploy Your First Azure VNet
# Create resource groupaz group create --name MyNetworkRG --location eastus
# Create VNet with subnetsaz network vnet create \ --name Production-VNet \ --resource-group MyNetworkRG \ --address-prefix 10.0.0.0/16 \ --subnet-name AppSubnet \ --subnet-prefix 10.0.1.0/24
# Create NAT Gatewayaz network public-ip create \ --resource-group MyNetworkRG \ --name NAT-Gateway-IP \ --sku Standard
az network nat gateway create \ --resource-group MyNetworkRG \ --name MyNATGateway \ --public-ip-addresses NAT-Gateway-IP
# Associate NAT Gatewayaz network vnet subnet update \ --resource-group MyNetworkRG \ --vnet-name Production-VNet \ --name AppSubnet \ --nat-gateway MyNATGateway
Cost: $40-80/month (NAT Gateway + data)
Azure VNet Architecture
Key Azure Networking Components
1. Virtual Network (VNet)
Key Difference from AWS: Subnets can span availability zones!
VNet Best Practices
- Use
/16
for production - Provides 65,536 IP addresses for growth - Private IP ranges only - Use 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16
- Plan for growth - Azure allows VNet expansion without downtime
- Document IP allocation - Maintain clear records to avoid overlaps
- Key difference from AWS - Subnets can span availability zones!
2. Network Security Groups (NSGs)
Network Security Groups (NSGs) are your first line of defense in Azure networking. Think of them as virtual firewalls that control inbound and outbound traffic to Azure resources. Unlike traditional firewalls, NSGs are stateful—meaning if you allow inbound traffic, the return traffic is automatically allowed.
Key characteristics:
- Can be applied at the subnet level (affects all resources in the subnet) or NIC level (affects individual VMs)
- Rules are evaluated by priority (lower numbers = higher priority)
- Default rules exist but can be overridden
- Completely free—no additional cost
Example: Web tier NSG
resource webNSG 'Microsoft.Network/networkSecurityGroups@2022-07-01' = { name: 'web-nsg' location: location properties: { securityRules: [ { name: 'allow-https' properties: { priority: 100 direction: 'Inbound' access: 'Allow' protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: 'Internet' destinationAddressPrefix: '*' } } ] }}
3. Azure Bastion
Azure Bastion solves a common security challenge: how do you securely access VMs in private subnets without exposing them to the internet? Traditionally, you’d use a “jump box” with a public IP, but that creates a security risk. Azure Bastion provides a fully managed PaaS service that lets you RDP/SSH to your VMs directly from the Azure portal over SSL.
How it works:
- Deployed in a dedicated subnet called
AzureBastionSubnet
- Connects to your VMs over private IP addresses
- No need to manage or patch bastion hosts
- Integrated with Azure AD for authentication
Cost: $140/month (Standard) + minimal data transfer charges
Azure Bastion Benefits
- No public IPs - VMs remain completely private
- No jump boxes - Eliminates need to manage bastion hosts
- Built-in DDoS protection - Automatic protection included
- Centralized access - Single point for secure RDP/SSH
4. NAT Gateway
VMs in private subnets can’t directly access the internet—they have no public IP. But what if they need to download updates, call external APIs, or access cloud services? That’s where NAT Gateway comes in. It provides outbound internet connectivity while keeping your VMs completely private.
How it works:
- Attach NAT Gateway to one or more subnets
- Automatically provides SNAT (Source Network Address Translation) for outbound traffic
- Scales automatically to handle traffic spikes
- Supports up to 64,000 concurrent connections per public IP
Cost: $33/month + $0.045/GB data processed
When to use:
- Private VMs need internet access for updates or external API calls
- You want predictable outbound IPs for allowlisting
- You need high-scale outbound connectivity
Hub-and-Spoke Architecture
Hub-and-spoke is the recommended architecture pattern for enterprise Azure deployments. Instead of creating isolated VNets for each application, you establish a central “hub” VNet that contains shared services (firewall, VPN gateway, DNS) and connect multiple “spoke” VNets to it via VNet peering.
Why use hub-and-spoke?
- Centralized security: All traffic flows through the hub’s Azure Firewall for inspection
- Simplified connectivity: On-premises networks connect once to the hub, not to each spoke
- Cost efficiency: Share expensive resources (VPN Gateway, Firewall) across multiple applications
- Isolation: Each spoke remains isolated from other spokes unless explicitly allowed
Architecture Overview
In this architecture:
- Hub VNet contains shared infrastructure: Azure Firewall for traffic inspection, VPN Gateway for on-premises connectivity, and Azure Bastion for secure VM access
- Spoke VNets host your applications and databases, isolated from each other
- VNet Peering connects spokes to the hub with low latency and high bandwidth
- Traffic flow: All inter-spoke traffic and internet-bound traffic routes through the hub’s firewall
Implementation with Bicep
Here’s how to implement this architecture using Azure Bicep templates:
// Hub VNetresource hubVnet 'Microsoft.Network/virtualNetworks@2022-07-01' = { name: 'hub-vnet' location: location properties: { addressSpace: { addressPrefixes: ['10.0.0.0/16'] } subnets: [ { name: 'AzureFirewallSubnet', properties: { addressPrefix: '10.0.0.0/26' } } { name: 'GatewaySubnet', properties: { addressPrefix: '10.0.1.0/27' } } { name: 'AzureBastionSubnet', properties: { addressPrefix: '10.0.2.0/26' } } ] }}
// Spoke VNetresource spokeVnet 'Microsoft.Network/virtualNetworks@2022-07-01' = { name: 'production-spoke' location: location properties: { addressSpace: { addressPrefixes: ['10.1.0.0/16'] } subnets: [ { name: 'AppSubnet', properties: { addressPrefix: '10.1.0.0/24' } } { name: 'DatabaseSubnet', properties: { addressPrefix: '10.1.1.0/24' } } ] }}
// VNet Peeringresource hubToSpoke 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2022-07-01' = { parent: hubVnet name: 'hub-to-spoke' properties: { allowVirtualNetworkAccess: true allowForwardedTraffic: true allowGatewayTransit: true remoteVirtualNetwork: { id: spokeVnet.id } }}
Azure Firewall
Azure Firewall is a cloud-native, fully managed network security service that protects your Azure Virtual Network resources. Unlike Network Security Groups (NSGs) which operate at the network interface or subnet level, Azure Firewall provides centralized, stateful traffic filtering at the VNet level with built-in high availability and unlimited scalability.
What makes it different from NSGs:
- Centralized management: One firewall protects multiple VNets (in hub-and-spoke)
- FQDN filtering: Block/allow traffic based on domain names, not just IPs
- Threat intelligence: Built-in threat detection from Microsoft’s security research
- Application rules: Layer 7 filtering (HTTP/HTTPS) with URL filtering
- Network rules: Traditional Layer 3-4 filtering (IP, port, protocol)
- NAT rules: Translate and filter inbound internet traffic
How it works:
Azure Firewall sits in a dedicated subnet (must be named AzureBastionSubnet
) within your hub VNet. All traffic from spoke VNets is routed through the firewall using User Defined Routes (UDRs). The firewall inspects traffic based on your configured rules and either allows or denies it.
Cost: $912/month (Standard tier) + $0.016/GB data processed
Important: This is expensive! Only use Azure Firewall when you need its advanced features. For simpler scenarios, NSGs are sufficient and free.
When to Use Azure Firewall
- Hub-and-spoke architectures - Centralized security inspection point
- FQDN filtering - Control outbound traffic by domain names
- Threat intelligence - Built-in threat detection and prevention
- Compliance requirements - Meet regulatory security standards
- Note: High cost ($912/month) - consider NSGs for simpler scenarios
ExpressRoute
ExpressRoute is Azure’s solution for dedicated, private connectivity between your on-premises infrastructure and Azure. Unlike VPN connections that go over the public internet, ExpressRoute connections use a private circuit provided by a connectivity partner (like AT&T, Verizon, or Equinix).
Why use ExpressRoute instead of VPN?
- Predictable performance: Dedicated bandwidth with consistent latency
- Higher bandwidth: Up to 100 Gbps vs VPN’s 10 Gbps maximum
- Better security: Traffic never traverses the public internet
- Lower latency: Direct connection to Azure’s network backbone
- SLA: 99.95% uptime guarantee (vs 99.9% for VPN Gateway)
How it works:
- You order a circuit from a connectivity provider (telco or colocation facility)
- The provider establishes a physical connection to Azure’s edge routers
- You configure BGP peering between your routers and Azure
- Traffic flows over the private circuit, bypassing the internet entirely
Common use cases:
- Migrating large datasets to Azure (faster than internet upload)
- Hybrid applications requiring low latency between on-premises and cloud
- Compliance requirements prohibiting data from traversing public internet
- Production workloads requiring predictable network performance
Comparison: ExpressRoute vs VPN Gateway
Bandwidth:
- ExpressRoute: 50 Mbps to 100 Gbps
- VPN Gateway: Up to 10 Gbps
Latency:
- ExpressRoute: Low and consistent
- VPN Gateway: Higher and variable
Cost:
- ExpressRoute: $55+/month (plus circuit provider fees)
- VPN Gateway: ~$140/month
Setup Time:
- ExpressRoute: Weeks (requires provider coordination)
- VPN Gateway: Minutes (fully self-service)
Best for:
- ExpressRoute: Production workloads, large data transfers, compliance requirements
- VPN Gateway: Dev/test, backup connectivity, quick setup needs
Private Link & Service Endpoints
Both Private Link and Service Endpoints solve the same problem: how do you securely access Azure PaaS services (like Storage, SQL Database, Cosmos DB) from your VNet without going over the public internet? However, they solve it in different ways.
Service Endpoints (FREE)
Service Endpoints extend your VNet’s identity to Azure services. When enabled, traffic to Azure services stays on Azure’s backbone network instead of going over the internet, and the service can restrict access to only your VNet.
How it works:
- Enable Service Endpoint on your subnet for specific Azure services
- Traffic to those services is routed through Azure’s backbone
- Azure service sees your VNet’s public IP range
- You configure firewall rules on the Azure service to allow only your VNet
Pros:
- Completely free
- Simple to configure
- Reduces internet egress costs
Cons:
- Service still has a public endpoint (just restricted)
- Can’t access from on-premises over ExpressRoute/VPN
- Service sees your public IP, not a private IP
Private Link ($7/month per endpoint)
Private Link gives Azure services a private IP address inside your VNet. The service appears as if it’s deployed directly in your VNet, with no public endpoint at all.
How it works:
- A Private Endpoint is created in your subnet
- This endpoint gets a private IP from your VNet’s address space
- DNS is configured to resolve the service’s FQDN to the private IP
- Traffic flows entirely over private IPs
Pros:
- Service has no public endpoint (more secure)
- Works from on-premises over ExpressRoute/VPN
- Service sees your private IP
- Can be used across VNets and subscriptions
Cons:
- Costs $7/month per endpoint + data processing
- Requires DNS configuration
- More complex setup
When to use which:
- Service Endpoints: Simple scenarios, cost-sensitive, Azure-only access
- Private Link: Need on-premises access, compliance requires no public endpoints, cross-VNet access
// Service Endpointresource subnet 'Microsoft.Network/virtualNetworks/subnets@2022-07-01' = { properties: { serviceEndpoints: [ { service: 'Microsoft.Storage' } { service: 'Microsoft.Sql' } ] }}
Cost Optimization
Monthly Cost Example:
NAT Gateway: $33Azure Bastion: $140Application Gateway: $125Data Transfer: $50Total: ~$350/month
Optimization Strategies
Service Endpoints Over Private Link
Use Service Endpoints (FREE) instead of Private Link ($7/month per endpoint) when you don't need private IPs. Service Endpoints route traffic over Azure backbone at no cost.
Service Endpoints Over Private Link
Use Service Endpoints (FREE) instead of Private Link ($7/month per endpoint) when you don't need private IPs. Service Endpoints route traffic over Azure backbone at no cost.
Single NAT Gateway for Dev/Test
Deploy one NAT Gateway instead of multiple in non-production environments to save ~$33/month per gateway. Accept reduced availability for cost savings.
Single NAT Gateway for Dev/Test
Deploy one NAT Gateway instead of multiple in non-production environments to save ~$33/month per gateway. Accept reduced availability for cost savings.
Review NSG Flow Logs
Enable and analyze NSG Flow Logs to identify traffic patterns, optimize routing, and reduce unnecessary data transfer costs.
Review NSG Flow Logs
Enable and analyze NSG Flow Logs to identify traffic patterns, optimize routing, and reduce unnecessary data transfer costs.
Use Azure Advisor
Leverage Azure Advisor's free recommendations for networking optimization, including unused resources and cost-saving opportunities.
Use Azure Advisor
Leverage Azure Advisor's free recommendations for networking optimization, including unused resources and cost-saving opportunities.
Remove Unused Resources
Delete unused Public IPs, Application Gateways, and VPN Gateways. Even stopped resources can incur charges.
Remove Unused Resources
Delete unused Public IPs, Application Gateways, and VPN Gateways. Even stopped resources can incur charges.
VNet Peering Over VPN
Use VNet Peering (data charges only) instead of VPN Gateway ($140/month) for Azure-to-Azure connectivity when possible.
VNet Peering Over VPN
Use VNet Peering (data charges only) instead of VPN Gateway ($140/month) for Azure-to-Azure connectivity when possible.
Common Issues
Issue 1: Can’t Access VMs
Solution: Use Azure Bastion instead of public IPs
Issue 2: High NAT Gateway Costs
Solution: Implement Service Endpoints for Azure services
Issue 3: VNet Peering Not Working
Checklist:
- Peering in both directions
- No overlapping CIDR blocks
- NSG rules allow traffic
- Route tables configured
Troubleshooting Tools
Azure Networking Troubleshooting Tools
- Network Watcher - Connectivity testing and path analysis
- NSG Flow Logs - Traffic analysis and security auditing
- Connection Monitor - End-to-end monitoring and alerting
- Azure Advisor - Optimization recommendations and best practices
- Network Performance Monitor - Performance metrics and diagnostics
Next Steps
Continue the series
Resources
Need help? Contact Quabyt for Azure networking support.