CAMPUX Cloud Bootcamp Lab · Networking ← All labs
Hands-On Lab · Intermediate
~35 min · Free · Cloud Shell · no VMs
Azure CLI · torn down at the end
Networking · Landing Zone

Hub-and-spoke: segmentation you can prove.

The landing-zone network topology every enterprise runs, built from the CLI in half an hour — a shared hub, two isolated spokes, and NSGs that enforce who may talk to whom. No virtual machines, so no bill, and the segmentation is provable from the routing itself.

Fig. 1 · Hub and two spokes — segmentation you can prove
Resource group · rg-hubspokeNSGpeeringpeeringHubvnet-hub 10.0.0.0/16Spoke Avnet-spoke-a 10.1.0.0/16Spoke Bvnet-spoke-b 10.2.0.0/16no spoke-to-spoke path
● Screen walkthrough Not yet recorded · ~7 min
Reel · 00:00 / 07:00

Draw a hub-and-spoke topology, peer the VNets, and prove segmentation with a route that is meant to be blocked.

Placeholder — the page below stands alone until the reel lands
Why

Why one flat network is a liability

The instinct of a beginner is to put everything in one virtual network because it "just works" — everything can reach everything. That is precisely the problem: when a single workload is compromised, a flat network lets the blast spread to all of them. The enterprise answer is hub-and-spoke. A central hub holds shared services (a firewall, a gateway, DNS); each workload lives in its own spoke, peered to the hub but not to its siblings. Traffic between workloads is routed and inspected on purpose, never by accident. This lab builds that shape and then demonstrates the isolation — that two spokes genuinely cannot reach each other — without spinning up a single chargeable resource.

You will create a hub and two spokes with non-overlapping address spaces, peer each spoke to the hub, confirm the spokes are not peered to one another, and add an NSG that spells out the allowed and denied paths as explicit rules.

A flat network trusts everything once. Segmentation makes trust a decision.

Before you begin — one-time setup

You need a free Azure account, the Azure CLI (az), then be signed in with az login. First time? The 15-minute Set up your machine page covers the account, the installs (winget / brew / apt), and sign-in. Prefer zero installs? Run everything in Azure Cloud Shell (Bash), preinstalled and already signed in.

The companion repository

This page is the whole lab; a Bicep version of the same topology is in github.com/kloudcaptain/campux-labs under lab-hub-spoke-networking. Run the commands in Azure Cloud Shell (Bash). Virtual networks, peerings, and NSGs have no hourly charge — this lab is genuinely free, VMs are what would have cost money and we deliberately use none.

Setup

A hub and two spokes

Address spaces must not overlap or peering will refuse them. Give the hub 10.0.0.0/16 and the spokes their own /16s, each with a workload subnet.

# Windows/Git Bash: stop it mangling /subscriptions/... arguments (harmless on macOS/Linux)
export MSYS_NO_PATHCONV=1

RG="campux-lab-net-rg"
az group create -n "$RG" -l eastus

# hub
az network vnet create -g "$RG" -n hub-vnet --address-prefix 10.0.0.0/16 \
  --subnet-name shared --subnet-prefix 10.0.1.0/24

# spoke 1
az network vnet create -g "$RG" -n spoke1-vnet --address-prefix 10.1.0.0/16 \
  --subnet-name workload --subnet-prefix 10.1.1.0/24

# spoke 2
az network vnet create -g "$RG" -n spoke2-vnet --address-prefix 10.2.0.0/16 \
  --subnet-name workload --subnet-prefix 10.2.1.0/24
Checkpoint Three virtual networks exist with distinct address spaces. Nothing can talk to anything yet — a fresh VNet is an island until you peer it. That default-deny-between-networks is the foundation the whole topology is built on.
Step 1

Peer each spoke to the hub

Peering is directional, so each link needs two halves — spoke→hub and hub→spoke. Create all four.

for S in spoke1 spoke2; do
  az network vnet peering create -g "$RG" -n "${S}-to-hub" \
    --vnet-name "${S}-vnet" --remote-vnet hub-vnet --allow-vnet-access
  az network vnet peering create -g "$RG" -n "hub-to-${S}" \
    --vnet-name hub-vnet --remote-vnet "${S}-vnet" --allow-vnet-access
done
Checkpoint Confirm both links report Connected — the state you want; anything else (usually Disconnected) means one half of a pair is missing:
az network vnet peering list -g "$RG" --vnet-name hub-vnet \
  --query "[].{name:name, state:peeringState}" -o table
Step 2

Prove the spokes are isolated

This is the segmentation payoff, and it needs no traffic test — the routing tells the truth. Azure VNet peering is non-transitive: spoke1 peers with the hub and spoke2 peers with the hub, but that does not connect spoke1 to spoke2. List spoke1's peerings and see that the hub is its only neighbour.

az network vnet peering list -g "$RG" --vnet-name spoke1-vnet \
  --query "[].{name:name, remote:remoteVirtualNetwork.id}" -o table
Checkpoint Spoke1 lists exactly one peering, and its remote network is hub-vnet — never spoke2-vnet. There is no route from spoke1 to spoke2, so traffic between the two workloads cannot flow. You have proven the isolation from the network's own configuration, which is exactly how an auditor would check it.
Step 3

Make the intent explicit with an NSG

Non-transitive peering already isolates the spokes, but real landing zones state their rules out loud so intent survives future changes. Attach an NSG to spoke1's workload subnet that allows the hub's range and denies spoke2's range explicitly.

az network nsg create -g "$RG" -n spoke1-nsg

az network nsg rule create -g "$RG" --nsg-name spoke1-nsg -n allow-hub \
  --priority 100 --direction Inbound --access Allow --protocol '*' \
  --source-address-prefixes 10.0.0.0/16 --destination-address-prefixes '*' \
  --destination-port-ranges '*'

az network nsg rule create -g "$RG" --nsg-name spoke1-nsg -n deny-spoke2 \
  --priority 200 --direction Inbound --access Deny --protocol '*' \
  --source-address-prefixes 10.2.0.0/16 --destination-address-prefixes '*' \
  --destination-port-ranges '*'

az network vnet subnet update -g "$RG" --vnet-name spoke1-vnet -n workload \
  --network-security-group spoke1-nsg
Checkpoint List the rules in priority order and read the policy off the page — allow the hub at 100, deny spoke2 at 200:
az network nsg rule list -g "$RG" --nsg-name spoke1-nsg \
  --query "sort_by([].{p:priority,name:name,access:access,src:sourceAddressPrefix}, &p)" -o table
Two layers now enforce the same intent: routing that offers no path, and a rule that would deny it even if a path appeared. Defence in depth, stated in code.
Down

Tear it down

Everything is in one resource group — delete it and confirm.

az group delete -n campux-lab-net-rg --yes
az group exists -n campux-lab-net-rg      # -> false
Checkpoint The group is gone. Because you used no VMs, gateways, or firewalls, this lab cost nothing even while it ran — the topology is the lesson, not the compute.
End

What you can now honestly claim

You built a hub-and-spoke topology, peered spokes to a hub, demonstrated that non-transitive peering keeps the spokes isolated, and expressed that isolation as explicit NSG rules. That is the networking backbone of every Azure landing zone in the job descriptions — "segmentation and least-privilege connectivity between workloads" is this, exactly. The next step in a real design is putting a firewall or a gateway in the hub so spoke-to-spoke traffic can be forced through inspection when it is wanted; the shape you just built is what that inspection plugs into.

Footnotes
  1. Azure VNet peering is non-transitive by design: peering A-hub and B-hub never implies A-B. To allow controlled spoke-to-spoke traffic you route it through a network virtual appliance or Azure Firewall in the hub, using user-defined routes — which is why the hub exists at all.
  2. Virtual networks, subnets, peerings, and NSGs carry no hourly charge; you are billed for data processed by gateways and firewalls and for VM compute, none of which this lab creates. That is what makes a networking lab safe to leave running while you read — though tearing it down is still the habit to keep.