Theoretical Foundation: Create and configure virtual networks and subnets
1. Initial Intuitionβ
Think about how a company organizes its physical office. There's a reception area accessible to everyone, a general work area, a server room with restricted access, and a meeting room for clients. Each area has its access rules. People within the same floor communicate directly; to talk to another floor, they go through the elevator.
In Azure, the Virtual Network (VNet) is this building. It's the private and isolated network space where your resources live. Subnets are the floors or rooms: logical divisions within the VNet that allow you to organize resources and apply different traffic controls for each segment.
A VM in the application subnet talks directly with a VM in the database subnet (same building), but traffic coming from the internet needs to pass through a controlled gatekeeper. This isolation and organization are the central purpose of VNets and subnets.
2. Contextβ
The VNet is the foundation of network infrastructure in Azure. Virtually every resource that needs to communicate with other resources or the internet goes through a VNet.
Azure manages the physical network infrastructure. You manage the logical topology: which IP addresses exist, how segments are divided, which traffic rules apply, and how networks connect to each other.
Everything we've studied so far (users, groups, RBAC) is about who can manage the resources. VNets are about how resources communicate. They are complementary dimensions of Azure security and operation.
3. Building the Conceptsβ
3.1 IP Addressing and CIDR Notationβ
Before talking about VNets, it's necessary to understand how IP addresses are organized. A VNet is defined by a range of IP addresses, expressed in CIDR (Classless Inter-Domain Routing) notation.
CIDR notation has the format X.X.X.X/Y, where:
X.X.X.Xis the base address/Yis the prefix, which indicates how many bits are fixed (the network part)
Practical examples:
| CIDR Notation | Available addresses | Range |
|---|---|---|
10.0.0.0/8 | 16,777,216 | 10.0.0.0 to 10.255.255.255 |
10.0.0.0/16 | 65,536 | 10.0.0.0 to 10.0.255.255 |
10.0.0.0/24 | 256 | 10.0.0.0 to 10.0.0.255 |
10.0.1.0/24 | 256 | 10.0.1.0 to 10.0.1.255 |
10.0.0.0/28 | 16 | 10.0.0.0 to 10.0.0.15 |
The higher the number after the slash, the smaller the address block.
3.2 Private Address Spacesβ
Azure recommends using private IP ranges (RFC 1918) for VNets:
| Private range | CIDR | Typical use |
|---|---|---|
10.0.0.0/8 | Up to 10.255.255.255 | Large corporate networks |
172.16.0.0/12 | Up to 172.31.255.255 | Medium corporate networks |
192.168.0.0/16 | Up to 192.168.255.255 | Smaller networks |
Using private addresses ensures there will be no conflict with public internet IPs. Using public addresses in a VNet is not recommended and can cause routing problems.
3.3 The Virtual Network (VNet)β
A VNet is an Azure resource that defines an isolated IP address space. Fundamental characteristics:
- Regional scope: a VNet exists in a single Azure region. VMs in different regions need specific connectivity mechanisms (VNet Peering or VPN).
- Subscription scope: a VNet belongs to a subscription and a Resource Group.
- Isolation by default: different VNets are completely isolated from each other by default. Resources in VNet-A cannot talk to resources in VNet-B without explicit configuration.
- Multiple address spaces: a VNet can have more than one CIDR block associated, allowing future expansion without recreating the VNet.
3.4 Subnetsβ
A subnet is a subdivision of the VNet's address space. It must be a subset of the VNet's CIDR.
Example:
- VNet:
10.0.0.0/16(65,536 addresses) - Subnet-Frontend:
10.0.1.0/24(256 addresses) - Subnet-Backend:
10.0.2.0/24(256 addresses) - Subnet-Database:
10.0.3.0/24(256 addresses) - Subnet-Management:
10.0.4.0/24(256 addresses)
Addresses reserved by Azure in each subnet: Azure automatically reserves 5 addresses in each subnet:
| Address | Use |
|---|---|
First (ex: 10.0.1.0) | Network address |
Second (ex: 10.0.1.1) | Default gateway (Azure) |
Third (ex: 10.0.1.2) | DNS mapped to Azure DNS |
Fourth (ex: 10.0.1.3) | Reserved for future use |
Last (ex: 10.0.1.255) | Broadcast |
This means a /24 subnet has 256 total addresses, but only 251 available for resources.
Important implication: the minimum subnet size supported by Azure is /29, which has 8 total addresses and only 3 available for resources. Plan with plenty of room.
3.5 Special Types of Subnetsβ
Some subnets have reserved names and behaviors:
| Reserved name | Purpose | Required? |
|---|---|---|
| GatewaySubnet | Hosts VPN Gateway and ExpressRoute Gateway | Yes, if using these services |
| AzureFirewallSubnet | Hosts Azure Firewall | Yes, if using Azure Firewall |
| AzureFirewallManagementSubnet | Azure Firewall management | Yes, in certain Firewall modes |
| AzureBastionSubnet | Hosts Azure Bastion | Yes, if using Azure Bastion |
The GatewaySubnet deserves special attention: it must be at least /27 (recommended /27 or larger), cannot have an associated NSG, and cannot host other resources besides gateways.
3.6 Subnet Delegationβ
Subnet delegation is a configuration that reserves a subnet exclusively for a specific Azure service. When a subnet is delegated, only that service can deploy resources in it.
Examples of services that use delegation:
Microsoft.ContainerInstance/containerGroups(Azure Container Instances)Microsoft.Web/serverFarms(App Service Regional VNet Integration)Microsoft.Sql/managedInstances(Azure SQL Managed Instance)Microsoft.NetApp/volumes(Azure NetApp Files)
Delegation is necessary because these services need special control over the subnet's address space and routes.
4. Structural Viewβ
How Resources Communicate Within a VNetβ
By default, all resources within a VNet can communicate freely with each other, regardless of being in different subnets. Isolation between subnets requires explicit configuration via Network Security Groups (NSGs), which we'll study in later modules.
5. Practical Operationβ
VNet Lifecycleβ
Important and Non-Obvious Behaviorsβ
Address spaces cannot overlap with connected networks: if you plan to connect your VNet with another VNet via peering, or with an on-premises network via VPN, the address spaces cannot overlap. For example, if your VNet uses 10.0.0.0/16 and the on-premises network also uses 10.0.0.0/16, routing will become ambiguous and the connection will fail. Plan addressing considering all networks that will need to connect.
Subnets cannot be easily resized: you can expand a subnet's CIDR (make it larger) only if there's no conflict with other subnets, and only if there are no resources deployed in it with addresses that fall outside the new range. In practice, reducing a subnet is impossible while there are resources in it. Plan with plenty of room from the beginning.
Adding address spaces to the VNet: you can add additional CIDR blocks to an existing VNet. What you cannot do is modify or remove an address space that's already in use. This allows gradual VNet expansion without recreating everything.
VNet has no cost by itself: creating a VNet and subnets has no direct cost. Network costs in Azure come from data transfer (especially between regions), public IP addresses, gateways, and other network resources.
DNS by default: by default, Azure provides DNS resolution for names within the VNet using Azure DNS (168.63.129.16). VMs in the same VNet can resolve each other by hostname without additional configuration. For custom or on-premises name resolution, it's necessary to configure a custom DNS server on the VNet.
6. Implementation Methodsβ
6.1 Azure Portalβ
When to use: initial creation, exploration, point adjustments.
Path: Create a resource > Networking > Virtual Network
The creation wizard in the portal has four tabs:
- Basics: name, region, resource group
- IP Addresses: VNet address space, subnet creation
- Security: Azure Bastion, Azure Firewall, DDoS Protection (optional)
- Tags: organization metadata
Advantage: the portal validates CIDR conflicts in real-time and warns about configuration issues.
Limitation: doesn't scale for multiple VNets or repeatable environments.
6.2 Azure CLIβ
Create VNet with address space:
az network vnet create \
--name vnet-producao \
--resource-group rg-networking \
--location brazilsouth \
--address-prefix 10.0.0.0/16
Add subnets:
# Frontend subnet
az network vnet subnet create \
--name subnet-frontend \
--vnet-name vnet-producao \
--resource-group rg-networking \
--address-prefix 10.0.1.0/24
# Backend subnet
az network vnet subnet create \
--name subnet-backend \
--vnet-name vnet-producao \
--resource-group rg-networking \
--address-prefix 10.0.2.0/24
# GatewaySubnet (no NSG, no other resources)
az network vnet subnet create \
--name GatewaySubnet \
--vnet-name vnet-producao \
--resource-group rg-networking \
--address-prefix 10.0.255.0/27
Add second address space to existing VNet:
az network vnet update \
--name vnet-producao \
--resource-group rg-networking \
--add addressSpace.addressPrefixes "10.1.0.0/16"
Create subnet with delegation for Azure Container Instances:
az network vnet subnet create \
--name subnet-containers \
--vnet-name vnet-producao \
--resource-group rg-networking \
--address-prefix 10.0.10.0/24 \
--delegations "Microsoft.ContainerInstance/containerGroups"
List subnets of a VNet:
az network vnet subnet list \
--vnet-name vnet-producao \
--resource-group rg-networking \
--output table
6.3 PowerShell (Az Module)β
# Create VNet
$vnet = New-AzVirtualNetwork `
-Name "vnet-producao" `
-ResourceGroupName "rg-networking" `
-Location "brazilsouth" `
-AddressPrefix "10.0.0.0/16"
# Add frontend subnet
Add-AzVirtualNetworkSubnetConfig `
-Name "subnet-frontend" `
-VirtualNetwork $vnet `
-AddressPrefix "10.0.1.0/24"
# Add backend subnet
Add-AzVirtualNetworkSubnetConfig `
-Name "subnet-backend" `
-VirtualNetwork $vnet `
-AddressPrefix "10.0.2.0/24"
# Save changes to the VNet
$vnet | Set-AzVirtualNetwork
Get information about an existing VNet:
Get-AzVirtualNetwork `
-Name "vnet-producao" `
-ResourceGroupName "rg-networking" |
Select-Object Name, Location, @{Name="AddressSpace";Expression={$_.AddressSpace.AddressPrefixes}},
@{Name="Subnets";Expression={$_.Subnets | Select-Object Name, AddressPrefix}}
6.4 Bicep (Infrastructure as Code)β
param location string = resourceGroup().location
resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
name: 'vnet-producao'
location: location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: [
{
name: 'subnet-frontend'
properties: {
addressPrefix: '10.0.1.0/24'
}
}
{
name: 'subnet-backend'
properties: {
addressPrefix: '10.0.2.0/24'
}
}
{
name: 'subnet-database'
properties: {
addressPrefix: '10.0.3.0/24'
}
}
{
name: 'GatewaySubnet'
properties: {
addressPrefix: '10.0.255.0/27'
}
}
{
name: 'AzureBastionSubnet'
properties: {
addressPrefix: '10.0.254.0/26'
}
}
]
}
}
7. Control and Securityβ
Subnet Segmentation as a Security Principleβ
Separation into subnets is not just organizational: it's the basis for applying different security controls to each application layer:
This layered segmentation model (frontend, backend, database, management) is the reference architecture for web applications in Azure. Each layer stays in its subnet, and NSGs control traffic between them.
Service Endpoints vs. Private Endpointsβ
Two mechanisms that modify how Azure resources access PaaS services (like Storage, SQL, Key Vault) from a subnet:
| Mechanism | How it works | When to use |
|---|---|---|
| Service Endpoint | Routes traffic to the PaaS service through Azure's backbone network, without going through the internet. The PaaS resource still has a public IP. | Basic security, no need for private IP for the service |
| Private Endpoint | Injects a NIC with private IP from the subnet for the PaaS service. The service becomes accessible via private IP from the VNet. | High security, PaaS service accessible only from within the VNet |
Service Endpoints are configured on the subnet. Private Endpoints are separate resources that associate with the subnet.
8. Decision Makingβ
How to size the VNet address space?β
| Situation | Recommendation | Reason |
|---|---|---|
| Small production environment (< 100 VMs) | /22 (1,022 useful addresses) | Sufficient space with room to grow |
| Medium production environment (100-500 VMs) | /20 (4,094 useful addresses) | Room for growth and services |
| Enterprise environment or central hub | /16 (65,531 useful addresses) | Space for multiple subnets and managed services |
| Development environment | /24 (251 useful addresses) | Lower planning cost, temporary environment |
How to size each subnet?β
| Subnet type | Recommended size | Reason |
|---|---|---|
| Workload subnet (VMs) | /24 or larger | Flexibility for growth |
| GatewaySubnet | /27 (minimum) | Service requirement |
| AzureBastionSubnet | /26 (minimum) | Service requirement |
| AzureFirewallSubnet | /26 (minimum) | Service requirement |
| Managed service subnet (ex: AKS, SQL MI) | /24 or larger | Managed services consume many IPs |
| Private Endpoints subnet | /27 or larger | Each Private Endpoint uses one IP |
One VNet per environment or shared?β
| Approach | When to use | Trade-off |
|---|---|---|
| Separate VNet by environment (prod, dev, staging) | Complete isolation between environments, strict compliance | More VNets to manage, connectivity via peering if needed |
| Shared VNet with separate subnets | Small teams, simple environments | Less isolation, NSGs required for separation |
| Hub-Spoke (one central VNet connected to spoke VNets) | Enterprise, multiple teams, shared services (Firewall, VPN) | More complex architecture, more scalable |
9. Best Practicesβ
Plan IP addressing before creating any VNet: the address space is hard to change after resources are deployed. Map all networks that will need to connect (other VNets, on-premises network) and ensure there's no overlap. An IPAM (IP Address Management) document is highly recommended.
Reserve space for managed services: Azure Kubernetes Service (AKS), SQL Managed Instance, and other managed services consume much more IP addresses than you might think. A medium AKS cluster can need hundreds of IPs. Size subnets for these services generously.
Use consistent naming conventions: names like snet-frontend-prod-brazilsouth (type-purpose-environment-region) facilitate management and automation. Azure recommends that subnet names start with snet- to distinguish from other network resources.
Create one subnet per logical tier, not per VM: the subnet is a network policy unit, not a container for a single VM. All frontend VMs go in subnet-frontend, all database ones go in subnet-database.
Always reserve the GatewaySubnet even if you don't use it now: creating the GatewaySubnet in the initial VNet ensures the address space is reserved for future use. Adding it later may be impossible if other blocks are already occupied.
Don't use /28 or smaller for workload subnets: with only 11 available addresses (16 minus 5 reserved), a /28 subnet gets full with less than 10 VMs. Always prefer /24 or larger for subnets hosting VMs.
10. Common Errorsβ
Creating VNets with overlapping address spaces
The company has a production VNet with 10.0.0.0/16 and an on-premises network that also uses 10.0.0.0/16. When they try to connect via VPN, the connection fails with ambiguous routing errors. To resolve this, it's necessary to recreate the VNet with a different space and redeploy all resources, which is enormous work. The solution is to map all existing address spaces before creating any new VNet.
Sizing subnets too small
An administrator creates a /27 subnet (27 useful addresses) for an AKS cluster. AKS starts to expand and soon there are no more available IPs; new pods stay in Pending because they can't get an IP. For AKS especially, /24 subnets or larger are the minimum recommended.
Associating NSG to GatewaySubnet
Azure doesn't allow associating NSGs to GatewaySubnet (and issues a warning, but some users ignore it). Even when the association is made, it can cause connectivity problems in the gateway. GatewaySubnet should always remain without NSG.
Confusing VNet address space with subnet's
The VNet has 10.0.0.0/16. The administrator creates a subnet with 10.1.0.0/24, which is outside the VNet's space. Azure rejects the creation with an error. The subnet must always be within the VNet's address space.
Not planning for peering before creating VNets
Two teams create their VNets independently, both using 10.0.0.0/16. Later they discover they need to connect the two VNets via peering. Since the spaces overlap, peering cannot be created. One of the teams needs to recreate their VNet with a different space.
11. Operation and Maintenanceβ
IP Address Usage Monitoringβ
To check how many IPs are in use in each subnet:
# List available IPs in a subnet
az network vnet subnet show \
--name subnet-backend \
--vnet-name vnet-producao \
--resource-group rg-networking \
--query "{Nome:name, Prefix:addressPrefix, DisponivelIPs:ipConfigurations}" \
--output json
The ipConfigurations field lists all assigned IPs. The difference between the subnet's total addresses (minus 5 reserved) and the number of ipConfigurations is the available capacity.
Expanding VNet with New Address Spaceβ
# Add new CIDR block without affecting existing resources
az network vnet update \
--name vnet-producao \
--resource-group rg-networking \
--add addressSpace.addressPrefixes "10.1.0.0/16"
# Create new subnet in the new space
az network vnet subnet create \
--name subnet-expansion \
--vnet-name vnet-producao \
--resource-group rg-networking \
--address-prefix 10.1.0.0/24
Azure Network Watcherβ
Network Watcher is Azure's network diagnostics service. Relevant functionalities for VNets:
- Topology: graphical view of a region's network topology
- IP Flow Verify: checks if a packet would be allowed or denied between two points, based on NSG rules
- Effective Routes: shows effective routes of a specific NIC
- Connection Troubleshoot: diagnoses connectivity between two endpoints
# Check if traffic from VM to an IP would be allowed
az network watcher test-ip-flow \
--vm /subscriptions/<sub-id>/resourceGroups/rg-producao/providers/Microsoft.Compute/virtualMachines/vm-backend \
--direction Inbound \
--protocol TCP \
--local 10.0.2.4:1433 \
--remote 10.0.1.4:12345 \
--resource-group rg-networking \
--watcher-resource-group NetworkWatcherRG
Important Limitsβ
| Item | Default limit | Adjustable? |
|---|---|---|
| VNets per subscription per region | 1,000 | Yes, via support |
| Subnets per VNet | 3,000 | No |
| Address spaces per VNet | 200 | No |
| Private IP addresses per VNet | 65,536 (per /16 block) | No (add more blocks) |
| Reserved addresses per subnet | 5 | No |
12. Integration and Automationβ
Hub-Spoke Topology with VNet Peeringβ
The hub-spoke architecture is the enterprise standard for organizing multiple VNets:
In hub-spoke, shared services (Firewall, VPN, DNS, Bastion) stay in the central hub, and each spoke has its own workload subnets. Traffic between spokes goes through the hub (and the Firewall), ensuring centralized visibility and control.
Automation with Azure Policyβ
Azure Policy can ensure VNet compliance automatically:
- Require all VNets in a subscription to use a specific address range
- Require GatewaySubnet to have a minimum size
- Require certain subnets to have associated NSGs
- Require Service Endpoints to be enabled for Storage and SQL
# Example: assign policy that requires NSG on all subnets
az policy assignment create \
--name "require-nsg-on-subnets" \
--policy "/providers/Microsoft.Authorization/policyDefinitions/2c2be004-5c73-4e68-9f32-f9e9b13f5f4e" \
--scope "/subscriptions/<sub-id>"
VNets in Bicep with Reusable Modulesβ
For organizations managing multiple environments, creating reusable Bicep modules for VNets standardizes creation:
// Module: modules/vnet.bicep
param vnetName string
param location string
param addressPrefixes array
param subnets array
resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
name: vnetName
location: location
properties: {
addressSpace: {
addressPrefixes: addressPrefixes
}
subnets: [for subnet in subnets: {
name: subnet.name
properties: {
addressPrefix: subnet.prefix
}
}]
}
}
output vnetId string = vnet.id
output subnetIds array = [for (subnet, i) in subnets: vnet.properties.subnets[i].id]
13. Final Summaryβ
Essential points:
- A VNet is a private and isolated network space in Azure, defined by one or more CIDR blocks. It exists in a single region and a single subscription.
- Subnets are subdivisions of the VNet's address space. Azure always reserves 5 addresses per subnet (first, second, third, fourth, and last).
- By default, all resources within a VNet communicate freely with each other, regardless of being in different subnets. Isolation requires NSGs.
- Different VNets are completely isolated from each other by default. Peering or VPN is needed to connect them.
Critical differences:
- VNet address space vs. subnet CIDR: the subnet must be a subset of the VNet space. Creating a subnet with CIDR outside the VNet space generates an error.
- Service Endpoint vs. Private Endpoint: Service Endpoint routes traffic through the Azure backbone maintaining the service's public IP; Private Endpoint injects a private IP from the VNet into the PaaS service.
- GatewaySubnet vs. regular subnets: GatewaySubnet has a mandatory name, cannot have NSG, and hosts only gateways. Regular subnets can have NSGs and host any resource.
- Subnet delegation vs. regular subnet: delegated subnet is reserved exclusively for one type of Azure service; regular subnets can host any resource.
What needs to be remembered:
- The minimum supported subnet size is
/29, but in practice use/24or larger for workload subnets. - The GatewaySubnet must be at least
/27and cannot have NSG. - The AzureBastionSubnet must be at least
/26. - The planned address space must consider all networks that will need to connect (other VNets, on-premises) to avoid overlap.
- Azure reserves 5 addresses per subnet: take this into account when sizing.
- VNets are free; network costs come from resources like gateways, data transfer between regions, and public IP addresses.
- Planning the address space before creating the VNet is much easier than modifying it later.