Multi-Cloud: Azure & GCP

Azure Compute & Networking

18 min Lesson 3 of 28

Azure Compute & Networking

Azure's compute and networking primitives map closely to what you already know from AWS — but the naming, defaults, and mental model differ enough to trip up experienced engineers. This lesson covers the four pillars you will use in every real Azure deployment: Virtual Machines (VMs), Virtual Networks (VNets), Network Security Groups (NSGs), and Load Balancers. We close with the AWS-to-Azure equivalents so you can translate fluently between clouds.

Virtual Machines

Azure VMs live inside a Resource Group — a logical container that scopes billing, RBAC, and lifecycle management. Every resource you create (VM, disk, NIC, public IP) is a separate, addressable object, unlike AWS where some are implicit. This explicitness is a feature: you can delete a VM while retaining its OS disk, or swap a NIC to another VM.

VM sizes follow a naming scheme: Standard_D4s_v5 — family (D = general purpose), vCPUs (4), storage type (s = premium SSD eligible), and generation (v5). For production workloads choose v5 or later; older generations run on aging hardware with lower single-thread performance.

# Create a resource group az group create --name prod-rg --location eastus # Create a VM (Standard_D4s_v5, Ubuntu 22.04, SSH key auth, no public IP) az vm create \ --resource-group prod-rg \ --name web-01 \ --image Ubuntu2204 \ --size Standard_D4s_v5 \ --admin-username azureuser \ --ssh-key-values ~/.ssh/id_rsa.pub \ --vnet-name prod-vnet \ --subnet app-subnet \ --public-ip-address "" \ --nsg "" \ --os-disk-size-gb 64 \ --storage-sku Premium_LRS \ --zone 1

Key flags to internalize: --public-ip-address "" disables a public IP — production VMs should not be directly internet-accessible. --nsg "" skips auto-creation of a per-NIC NSG when you plan to manage NSGs at the subnet level, which is a cleaner security posture at scale. --zone 1 pins the VM to Availability Zone 1; always spread replicas across zones 1, 2, and 3 for HA.

Tip — Managed Disks and Premium SSD: Always use Managed Disks (--storage-sku Premium_LRS). They handle redundancy automatically, support snapshots as first-class resources, and are required for Availability Sets to provide the SLA. Unmanaged disks are legacy — never use them in new deployments.

Virtual Networks (VNets)

A VNet is Azure's equivalent of an AWS VPC. You define a CIDR block (e.g., 10.0.0.0/16) and carve it into subnets. Unlike AWS, subnets in a VNet are not Availability-Zone-scoped — a single subnet spans all zones in a region. Zone isolation is enforced at the resource level (VM, Load Balancer frontend IP, etc.), not the subnet level.

A recommended production layout separates concerns into at least three subnets: a frontend subnet (for Application Gateways), an application subnet (for VMs and App Services), and a data subnet (for managed databases). Use /24 blocks or larger — Azure reserves 5 IPs per subnet internally.

Azure VNet three-tier subnet layout VNet 10.0.0.0/16 (eastus) Frontend Subnet 10.0.1.0/24 Application Gateway NSG: allow 443 inbound App Subnet 10.0.2.0/24 VM web-01 VM web-02 NSG: allow 8080 from GW Data Subnet 10.0.3.0/24 Azure Database for PostgreSQL NSG: allow 5432 from App
Three-tier subnet layout inside a single Azure VNet — each subnet has its own NSG enforcing least-privilege traffic rules.

Network Security Groups (NSGs)

An NSG is a stateful packet filter — Azure's equivalent of an AWS Security Group, but with two critical differences. First, NSGs can be attached to subnets as well as individual NICs. Second, NSG rules have an explicit priority (100–4096, lower number wins) and can both allow and deny. This enables defense-in-depth: a subnet-level NSG blocks broad categories of traffic, while a per-NIC NSG handles exceptions for individual VMs.

# Create an NSG and attach to a subnet az network nsg create --resource-group prod-rg --name app-nsg # Allow inbound port 8080 from the Application Gateway subnet only az network nsg rule create \ --resource-group prod-rg \ --nsg-name app-nsg \ --name allow-gw-8080 \ --priority 100 \ --direction Inbound \ --access Allow \ --protocol Tcp \ --source-address-prefixes 10.0.1.0/24 \ --destination-port-ranges 8080 # Explicit deny-all to make intent clear (default rules already deny, but explicit is better) az network nsg rule create \ --resource-group prod-rg \ --nsg-name app-nsg \ --name deny-all-inbound \ --priority 4000 \ --direction Inbound \ --access Deny \ --protocol "*" \ --source-address-prefixes "*" \ --destination-port-ranges "*" # Attach NSG to a subnet (applies to all VMs in this subnet) az network vnet subnet update \ --resource-group prod-rg \ --vnet-name prod-vnet \ --name app-subnet \ --network-security-group app-nsg
Production pitfall — NSG evaluation order: When an NSG is attached to both a subnet AND a NIC, Azure evaluates both. For inbound traffic, the subnet NSG runs first; the NIC NSG runs second. Both must allow the traffic. For outbound, the NIC NSG runs first. This catches engineers who fix a subnet NSG but forget the NIC NSG is also blocking — or vice versa. Use az network watcher test-ip-flow to diagnose this fast.
Service Tags: Instead of hardcoding IP ranges, use Azure Service Tags in NSG rules. For example, --source-address-prefixes AzureLoadBalancer allows health probe traffic from the Azure infrastructure, and Internet represents all public IPs. Microsoft maintains these ranges automatically. This is the Azure equivalent of AWS prefix lists for managed services.

Azure Load Balancers

Azure offers two load-balancing products you will encounter constantly: the Standard Load Balancer (Layer 4, TCP/UDP) and the Application Gateway (Layer 7, HTTP/HTTPS). They map roughly to AWS NLB and ALB respectively.

The Standard Load Balancer is the workhorse for internal east-west traffic and VM-to-VM load distribution. Key concepts:

  • Frontend IP configuration — a private or public IP the LB listens on. For internal LBs, this is a private IP inside a subnet.
  • Backend pool — the set of VMs (or NICs) to distribute traffic to.
  • Health probe — TCP or HTTP probe; unhealthy VMs are removed from rotation. Default probe interval is 15 seconds with 2 consecutive failures triggering removal.
  • Load balancing rule — maps a frontend port to a backend port with a distribution algorithm (default: 5-tuple hash for persistence).
# Create an internal Standard Load Balancer az network lb create \ --resource-group prod-rg \ --name internal-lb \ --sku Standard \ --vnet-name prod-vnet \ --subnet app-subnet \ --frontend-ip-name lb-frontend \ --private-ip-address 10.0.2.100 \ --backend-pool-name app-pool # Add a TCP health probe on port 8080 az network lb probe create \ --resource-group prod-rg \ --lb-name internal-lb \ --name http-probe \ --protocol Http \ --port 8080 \ --path /healthz \ --interval 10 \ --threshold 2 # Create a load balancing rule: frontend 80 -> backend 8080 az network lb rule create \ --resource-group prod-rg \ --lb-name internal-lb \ --name http-rule \ --protocol Tcp \ --frontend-port 80 \ --backend-port 8080 \ --frontend-ip-name lb-frontend \ --backend-pool-name app-pool \ --probe-name http-probe \ --idle-timeout 15 \ --enable-tcp-reset true # Add VM NICs to the backend pool az network nic ip-config address-pool add \ --resource-group prod-rg \ --nic-name web-01VMNic \ --ip-config-name ipconfig1 \ --lb-name internal-lb \ --address-pool app-pool
Tip — Enable TCP Reset on idle timeout: Always set --enable-tcp-reset true on load balancing rules. Without it, idle connections silently time out and your application gets RST-less socket hangs. With TCP reset enabled, the LB sends RST packets to both sides when a connection goes idle, letting your app fail fast and reconnect cleanly. This is a common source of mysterious connection drops in production.

Cross-Cloud Equivalents

The table below maps the AWS primitives you know to their Azure counterparts. The concepts are identical; the APIs and defaults differ.

  • AWS VPCAzure VNet (subnets are region-wide, not AZ-scoped)
  • AWS Security GroupAzure NSG (can attach at subnet or NIC; has explicit deny rules)
  • AWS EC2 instanceAzure VM (in a Resource Group; NIC, disk, public IP are separate resources)
  • AWS ALBAzure Application Gateway (Layer 7, WAF-capable)
  • AWS NLBAzure Standard Load Balancer (Layer 4, zone-redundant with Standard SKU)
  • AWS Auto Scaling GroupAzure Virtual Machine Scale Sets (VMSS)
  • AWS Subnet (per-AZ)Azure Subnet (region-wide) — zone pinning is per-resource
Always use the Standard SKU: Azure has two load balancer SKUs — Basic and Standard. Never use Basic in production. Standard LBs support Availability Zones, SLA (99.99%), outbound rules, HA ports, and integration with NSG-enforced security. Basic LBs are open by default (no NSG = all traffic allowed) and have no SLA. Microsoft is retiring Basic LBs — treat them as non-existent.