Build an Azure Virtual Network from scratch: define an address space, carve it into public and private subnets, control traffic with network security groups, and give private resources outbound internet with a NAT gateway.
A Virtual Network (VNet) is your own private network inside Azure — you choose the IP range and how it is divided. Why: every VM, database, and load balancer attaches to a VNet, and the network design decides what can reach what.
Create a VNet with the address space 10.0.0.0/16 and a first subnet. (--query pulls just the id; we'll reuse names below.)
az network vnet create \
--resource-group learn-rg \
--name my-vnet \
--address-prefix 10.0.0.0/16 \
--subnet-name public --subnet-prefix 10.0.1.0/24The address space (e.g. 10.0.0.0/16 ≈ 65k addresses) is split into subnets (e.g. /24 ≈ 256). The split that matters: put internet-facing things (load balancers, web VMs) in one subnet and databases in another. Why: you then apply different firewall rules to each, keeping the database unreachable from outside.
Add a second subnet for private resources (e.g. databases)
az network vnet subnet create \
--resource-group learn-rg \
--vnet-name my-vnet \
--name private \
--address-prefix 10.0.2.0/24List the subnets to confirm
az network vnet subnet list --resource-group learn-rg \
--vnet-name my-vnet --query '[].{name:name, prefix:addressPrefix}' \
--output tableA network security group (NSG) is a set of allow/deny rules you attach to a subnet or a VM's network card. Why: it is your main access control — allow web traffic on port 443 from anywhere, but SSH (port 22) only from your office IP. Rules are evaluated by priority (lower number wins).
Create an NSG
az network nsg create --resource-group learn-rg --name web-nsgAllow HTTPS from anywhere (priority 100)
az network nsg rule create --resource-group learn-rg \
--nsg-name web-nsg --name allow-https \
--priority 100 --destination-port-ranges 443 \
--access Allow --protocol TcpAllow SSH only from one office IP — never open 22 to the world
az network nsg rule create --resource-group learn-rg \
--nsg-name web-nsg --name allow-ssh \
--priority 200 --source-address-prefixes 203.0.113.25/32 \
--destination-port-ranges 22 --access Allow --protocol TcpCreating rules does nothing until the NSG is attached to something. Why: associating it with the public subnet makes those rules govern every resource in that subnet, so you set the policy once for the whole tier.
Attach the NSG to the public subnet
az network vnet subnet update \
--resource-group learn-rg \
--vnet-name my-vnet --name public \
--network-security-group web-nsgResources in a VNet are private by default. A public IP is an internet-reachable address you attach to a load balancer, gateway, or VM. Why "Standard" + "Static": the Standard SKU is the modern default, and a static allocation keeps the same address across restarts so DNS and firewall allow-lists keep working.
Allocate a static, Standard-SKU public IP
az network public-ip create \
--resource-group learn-rg \
--name web-ip \
--sku Standard \
--allocation-method StaticA private subnet sometimes needs to reach OUT (to download updates) without being reachable FROM the internet. A NAT gateway allows that one-way flow. Note: it attaches to a subnet and needs a public IP; it costs money per hour, so remove it when experimenting.
Create the NAT gateway (reusing a public IP)
az network nat gateway create \
--resource-group learn-rg \
--name my-nat \
--public-ip-addresses web-ipAttach it to the private subnet so its VMs get outbound internet
az network vnet subnet update \
--resource-group learn-rg \
--vnet-name my-vnet --name private \
--nat-gateway my-nat