đź”—Creating Virtual Network Peering on Azure

Pratiksha kadamPratiksha kadam
5 min read

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

  1. SSH into VM1 using its public IP:

     ssh -i id_rsa azureuser@<vm1_public_ip>
    
  2. Ping VM2’s private IP:

     ping <vm2_private_ip>
    
  3. 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.


0
Subscribe to my newsletter

Read articles from Pratiksha kadam directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pratiksha kadam
Pratiksha kadam