Azure VNet Peering: Configure Bidirectional Links for Private Cross-VNet Traffic
A task guide to Azure VNet Peering: verify non-overlapping address spaces, create both sides of the handshake with Azure CLI, test private IP reachability, and recover from stuck or misconfigured links.
23 Mar 2026, 06:52 UTC

The Problem: Isolated Virtual Networks
Azure Virtual Networks (VNets) are isolated routing domains by default. A virtual machine in VNet A cannot reach a virtual machine in VNet B using a private IP address, even when both networks sit in the same region or subscription. VNet Peering removes that boundary by creating a bidirectional link that routes traffic across the Microsoft backbone network rather than the public internet.
The useful takeaway: Peering is a two-sided handshake, not a single switch. You must create a link from each VNet to the other, and the connection remains unusable until both sides exist. Peering is also not transitive: if VNet A peers with VNet B and VNet B peers with VNet C, VNet A still cannot reach VNet C without a direct peering link or a hub-and-spoke design using a Network Virtual Appliance (NVA).
Prerequisites and Constraints
Non-Overlapping Address Spaces
Each VNet uses a CIDR block (Classless Inter-Domain Routing notation, such as 10.0.0.0/16) to define its private IP range. The two address spaces must not overlap. If they do, the peering request fails immediately because Azure cannot build unambiguous routes between the networks.
Permissions
You need the Microsoft.Network/virtualNetworks/virtualNetworkPeerings/write permission on both virtual networks. The built-in Network Contributor role satisfies this requirement. If you use a custom role, confirm it includes that specific action at the VNet scope.
Regional Scope
Global VNet Peering connects networks across different Azure regions. Confirm that your subscription permits resource deployment in both target regions before you begin.
Establish the Bidirectional Peering Handshake
Run the following commands in Azure Cloud Shell or a local terminal where the Azure CLI is installed and you have run az login. Replace the placeholders with your actual subscription ID, resource group names, and VNet names.
Step 1: Create the Forward Link
az network vnet peering create \
--name VNetA-to-VNetB \
--resource-group rg-network-a \
--vnet-name VNetA \
--remote-vnet /subscriptions/<subscription-id>/resourceGroups/rg-network-b/providers/Microsoft.Network/virtualNetworks/VNetB \
--allow-vnet-access
Expected check: After creation, query the link state:
az network vnet peering show \
--resource-group rg-network-a \
--vnet-name VNetA \
--name VNetA-to-VNetB \
--query peeringState
The expected value is Initiated. Relevant risk: if you supply an incorrect --remote-vnet resource ID, the link stays in Initiated and never becomes connected.
Step 2: Create the Return Link
az network vnet peering create \
--name VNetB-to-VNetA \
--resource-group rg-network-b \
--vnet-name VNetB \
--remote-vnet /subscriptions/<subscription-id>/resourceGroups/rg-network-a/providers/Microsoft.Network/virtualNetworks/VNetA \
--allow-vnet-access
Expected check: Run the same az network vnet peering show command against VNetB. The peeringState should now read Connected. Both VNets must show Connected in the Azure Portal Peerings blade before traffic can flow.
Verify Connectivity and Diagnose Failures
Test Private IP Reachability
Deploy a test virtual machine in each VNet and note the private IP addresses. From the VM in VNet A, attempt to reach the VM in VNet B. On Windows, use Test-NetConnection -ComputerName <VNetB-private-IP> -Port <port>. On Linux, use nc -vz <VNetB-private-IP> <port>. ICMP echo (ping) is frequently blocked by the guest operating system firewall even when the network path is healthy, so test an application port when possible.
Use Network Watcher for Path Evidence
If the test fails, use Azure Network Watcher IP flow verify to confirm whether a Network Security Group (NSG) is dropping the traffic. This tool reports the effective security rules applied to the network interface, which separates network-layer blocks from application or guest-firewall issues.
Diagnostic Decision Table
| Observation | Likely Cause | Action |
|---|---|---|
Peering state remains Initiated |
Missing or incorrect return link | Verify the --remote-vnet resource ID and re-run the second az network vnet peering create command. |
State is Connected but traffic fails |
NSG rule or guest OS firewall | Run Network Watcher IP flow verify, then inspect inbound NSG rules and the VM firewall. |
| Peering creation returns an error | Overlapping address spaces | Compare the CIDR ranges of both VNets and adjust one before retrying. |
| Traffic flows A-to-B but not B-to-C | Transitive routing assumption | Add a direct peering between VNet A and VNet C, or route through an NVA in a hub VNet. |
Gateway Transit and Routing Limits
In a hub-and-spoke topology, a spoke VNet can use a virtual network gateway deployed in the hub VNet to reach on-premises networks. This is called Gateway Transit. On the hub VNet peering, set --allow-gateway-transit true. On the spoke VNet peering, set --use-remote-gateways true. The hub must already contain a VPN or ExpressRoute gateway; peering alone does not create one.
Remember the core limitation: VNet Peering does not build transitive routes. Plan for either full-mesh peering or a central NVA when more than two networks must communicate.
Recovery Options and State Changes
Creating a peering link changes VNet routing state. To remove connectivity, delete both links:
az network vnet peering delete \
--resource-group rg-network-a \
--vnet-name VNetA \
--name VNetA-to-VNetB
az network vnet peering delete \
--resource-group rg-network-b \
--vnet-name VNetB \
--name VNetB-to-VNetA
If you must change the address space of a VNet after peering is established, delete the peering links first, modify the address space, and then recreate the links. Attempting to resize a peered VNet in place can fail or leave the peering in an inconsistent state.
Practical result check: after recovery, confirm that the Peerings blade shows no active links and that private IP traffic between the former peers no longer succeeds.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.