đź”—Creating Virtual Network Peering on Azure


Introduction
In cloud computing, you often need resources in different virtual networks to talk to each other securely.
VNet peering in Azure is the solution.
In simple terms, it allows two VNets to connect so that resources (like virtual machines) can communicate with each other using private IPs, just as if they were on the same network.
Think of it like connecting two office LANs with a direct private cable instead of sending traffic through the public internet.
In this blog, we’ll walk through how to create VNet peering on Azure using Terraform for automation and few Azure CLI commands.
We’ll also implement security groups and NSG rules to keep your network safe.
What is VNet Peering?
VNet peering is a networking feature in Azure that lets you connect two VNets privately and securely. Once peered, traffic between the two VNets is routed through Microsoft’s private backbone network—never the public internet.
Example Use Case
VNet-A: Application servers
VNet-B: Database servers
With VNet peering, the application servers in one Application VNet can connect to the database servers in other VNet securely via private IP addresses.
Benefits
Low latency, high bandwidth communication between Virtual Networks.
No VPN gateways required, saving costs.
Secure traffic routing over Microsoft’s backbone.
Supports
cross-region peering
as well.
Step 1: Set Up Resource Group and VNets
We’ll start by creating a resource group and two VNets.
Using Azure CLI
az group create --name MyResourceGroup --location eastus
az network vnet create \
--resource-group MyResourceGroup \
--name VNetA \
--address-prefix 10.0.0.0/16 \
--subnet-name SubnetA \
--subnet-prefix 10.0.1.0/24
az network vnet create \
--resource-group MyResourceGroup \
--name VNetB \
--address-prefix 10.1.0.0/16 \
--subnet-name SubnetB \
--subnet-prefix 10.1.1.0/24
Step 2: Create VNet Peering
We need two peerings- one from VNetA → VNetB
and another from VNetB → VNetA.
Using Azure CLI
az network vnet peering create \
--name VNetA-to-VNetB \
--resource-group MyResourceGroup \
--vnet-name VNetA \
--remote-vnet VNetB \
--allow-vnet-access
az network vnet peering create \
--name VNetB-to-VNetA \
--resource-group MyResourceGroup \
--vnet-name VNetB \
--remote-vnet VNetA \
--allow-vnet-access
Step 3: Automating with Terraform
Instead of running CLI commands every time, let’s automate using Terraform.
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "rg" {
name = "MyResourceGroup"
location = "East US"
}
resource "azurerm_virtual_network" "vnet_a" {
name = "VNetA"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_virtual_network" "vnet_b" {
name = "VNetB"
address_space = ["10.1.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_virtual_network_peering" "peer_a_to_b" {
name = "VNetA-to-VNetB"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet_a.name
remote_virtual_network_id = azurerm_virtual_network.vnet_b.id
allow_virtual_network_access = true
}
resource "azurerm_virtual_network_peering" "peer_b_to_a" {
name = "VNetB-to-VNetA"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet_b.name
remote_virtual_network_id = azurerm_virtual_network.vnet_a.id
allow_virtual_network_access = true
}
Apply it:
terraform init
terraform apply -auto-approve
Step 4: Add Virtual Machines
Let’s add one VM in each VNet. VM1 will have a public IP for access, while VM2 will be private.
Terraform Snippet
resource "azurerm_linux_virtual_machine" "vm1" {
name = "VM1"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
size = "Standard_B1s"
admin_username = "azureuser"
network_interface_ids = [azurerm_network_interface.nic_vm1.id]
admin_ssh_key {
username = "azureuser"
public_key = tls_private_key.ssh.public_key_openssh
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
}
Once deployed, Login with SSH into VM1 and try pinging VM2’s private IP to test connectivity.
Step 5: Secure the Traffic with NSG Rules
By default, VNets won’t block communication, but we can use Network Security Groups (NSGs) to control what’s allowed. NSGs are like firewalls at the subnet or NIC level.
Terraform Snippet
resource "azurerm_network_security_group" "nsg_a" {
name = "NSG-A"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "Allow-SSH"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "Allow-ICMP"
priority = 110
direction = "Inbound"
access = "Allow"
protocol = "Icmp"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "10.1.0.0/16"
destination_address_prefix = "*"
}
}
Why Use Security Groups and NSG Rules?
Security groups (in AWS) and NSGs (in Azure) act as gatekeepers for your resources.
Protect VMs from unwanted access.
Allow you to define inbound and outbound rules.
Ensure only trusted networks or IP ranges can interact with your VMs.
Reduce the attack surface by limiting exposed ports.
In our example, NSGs allow:
Protocol SSH (22) only from specific ranges.
ICMP Protocol (ping) only between peered VNets.
Testing Connectivity
SSH into VM1 using its public IP:
ssh -i id_rsa azureuser@<vm1_public_ip>
Ping VM2’s private IP:
ping <vm2_private_ip>
SSH from VM1 to VM2:
ssh azureuser@<vm2_private_ip>
If all is set up correctly, VM1 should reach VM2 over the private VNet peering connection.
Cleanup:
When done testing, destroy cloud resources:
terraform destroy -auto-approve
Or delete the resource group:
az group delete --name MyResourceGroup --yes --no-wait
Conclusion
VNet peering in Azure is a powerful way to connect virtual networks securely without routing traffic over the internet. By combining Terraform automation with NSG rules, you can:
Build reproducible and secure infrastructure.
Control traffic flow between VNets with precision.
Enable private communication between application and database tiers.
This pattern is commonly used in multi-tier architectures, shared services models, and hybrid networking setups.
With just a few lines of Terraform and some CLI commands, you can set up a secure, scalable, and production-ready network on Azure.
Subscribe to my newsletter
Read articles from Pratiksha kadam directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
