---
cuppy_hub: azure
cuppy_path: reference/networking/vnets-subnets-and-peering.md
cuppy_section: docs
cuppy_doc: W40P-G895
cuppy_doc_uuid: 0ef78f5b-8557-4b2e-8bf4-127c436df2e4
cuppy_permalink: https://cuppy.io/azure/d/W40P-G895
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/reference/networking/vnets-subnets-and-peering
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: defb919c29424c555d8404f2b7742a0774119e3e7438a126282cee9f0eeb0b00
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Virtual networks, subnets and peering

## Addresses

- **Five addresses per subnet are reserved**: the network address, the default gateway (`.1`), two for Azure DNS mapping (`.2`, `.3`) and the broadcast address. A `/29` gives 3 usable addresses.
- **Subnet sizes:** IPv4 from `/29` to `/2`; IPv6 subnets are exactly `/64`. Subnets in one VNet can't overlap, and **peered VNets can't overlap** either: plan address space across every VNet that may ever peer, and on-premises ranges.
- Subnet size is hard to change once services are in it (App Service and Container Apps say it can't change). Size for scale-out plus platform upgrades.

## Subnets with required names or sizes

| Subnet | Requirement |
|---|---|
| `GatewaySubnet` (VPN, ExpressRoute) | That exact name; `/27` suits most configurations, coexistence needs more (`reference/networking/vpn-and-expressroute.md`) |
| `AzureFirewallSubnet` | That name, `/26` or larger; forced tunnelling also needs `AzureFirewallManagementSubnet` (`reference/networking/firewall-and-ddos.md`) |
| `AzureBastionSubnet` | That name, `/26` or larger (since November 2, 2021), with required NSG rules (`reference/networking/bastion.md`) |
| App Service / Functions VNet integration | Unused, `/28` or larger (`/26` when several plans share it), delegated to `Microsoft.Web/serverFarms` (`reference/app-service/configuration-and-networking.md`) |
| Container Apps, workload profiles | `/27` or larger, delegated to `Microsoft.App/environments` (`reference/container-apps/apps-ingress-and-scale.md`) |
| App Service Environment v3 | Empty, delegated to `Microsoft.Web/hostingEnvironments`, `/24` recommended (`reference/app-service/app-service-environment.md`) |
| Private endpoints | Any subnet that **isn't delegated** |

**Delegation** hands a subnet to one service, which then creates resources there and adds a **service association link**. Those links, NICs, private endpoints and network profiles are what stop a subnet from being deleted or re-delegated. List them in one call:

```bash
az network vnet subnet show -g <rg> --vnet-name <vnet> -n <subnet> \
  --query "{prefix:addressPrefix, delegations:delegations[].serviceName, ipConfigs:ipConfigurations[].id, privateEndpoints:privateEndpoints[].id, links:serviceAssociationLinks[].linkedResourceType}"
```

## Private subnets (default outbound access)

- **For network API versions released after March 31, 2026, subnets in new virtual networks have `defaultOutboundAccess: false`** (the portal already does this). VMs in them get no implicit internet egress: no package downloads, Windows activation or Windows Update until you add a NAT gateway, a firewall route, a public IP or Standard load balancer outbound rules.
- Existing virtual networks don't change, and templates on older API versions keep the old default. The spec doesn't state a default, so **set `defaultOutboundAccess` explicitly** on every subnet.
- Implicit default outbound IPs belong to Microsoft, can change, and don't support fragmented packets or ICMP. Making an existing subnet private takes effect for a VM after it's deallocated. Egress options: `reference/networking/outbound-connectivity.md`.

## Service endpoints or private endpoints

| | Service endpoint | Private endpoint |
|---|---|---|
| What it is | A subnet setting (`Microsoft.Storage`, `Microsoft.KeyVault`, …) | A NIC with a private IP in your subnet for one resource and sub-resource |
| Address the client uses | The service's **public** endpoint; the service sees your subnet | The private IP, through private DNS |
| Firewall rule on the service | VNet rule naming the subnet | None needed; public access can be disabled |
| Clients in other VNets or on-premises | Enable it on each client subnet; on-premises can't use it (allow its public NAT IPs instead) | Yes, with DNS |
| Cost and setup | No extra charge; no DNS | Charged per endpoint; a private DNS zone per service |

Private endpoints and DNS: `reference/networking/private-endpoints-and-dns.md`.

## Peering

- Create the peering **on both VNets**. The first side shows `Initiated`; the link works only when both show `Connected`. `Disconnected` means one link was deleted, or an address space changed without a sync: re-create the missing link, or run `az network vnet peering sync`.
- **Peering isn't transitive.** VNet1–VNet2 and VNet2–VNet3 give no VNet1–VNet3 path; peer them directly or route through a hub NVA or firewall (UDRs plus `allowForwardedTraffic`). Using the hub's VPN or ExpressRoute gateway needs `allowGatewayTransit` on the hub and `useRemoteGateways` on the spoke.
- **Default Azure name resolution doesn't cross peerings.** Use Azure Private DNS zones linked to each VNet, or a DNS server or Private Resolver.
- Address space changes on a peered VNet need the peering re-synced (`az network vnet peering sync`).

Errors: `reference/networking/errors.md`. Many VNets with managed hubs or policy-driven peering: `reference/networking/virtual-wan-and-network-manager.md`.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 107 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/azure/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
