Azure Networking + Terraform

Build Azure VNet Peering with Terraform

Once you understand Azure VNet Peering conceptually, the next step is to build it with Terraform. This helps turn private network-to-network connectivity into reusable infrastructure as code that can be reviewed, versioned, and deployed consistently.

This page shows a practical Azure VNet Peering Terraform example, explains important settings such as remote virtual network ID, forwarded traffic, gateway transit, and remote gateway usage, and gives you a strong foundation you can extend later into hub-and-spoke and global peering designs. :contentReference[oaicite:1]{index=1}

Quick summary

Before going deeper, here is the simplest way to think about Azure VNet Peering Terraform.

What Terraform code that creates a peering relationship between two Azure virtual networks.
Why It makes private network-to-network connectivity consistent, reviewable, and reusable.
When Use it whenever you want repeatable private VNet connectivity through infrastructure as code.
Where It fits into hub-and-spoke, shared services, multi-subscription, and multi-region network designs.
Who Cloud, DevOps, platform, and network teams usually manage it.
How Using azurerm_virtual_network_peering, usually once from each side for bidirectional peering. :contentReference[oaicite:2]{index=2}

Why use Terraform for Azure VNet Peering?

VNet peering can be created manually in the Azure portal, but Terraform is better when you need repeatable connectivity patterns, reviewable settings, and reusable multi-environment network foundations.

  • It keeps peering configuration in code instead of clicks.
  • It makes peering changes visible in Git and code review.
  • It reduces manual mistakes in remote network IDs and peering flags.
  • It helps teams standardize hub-and-spoke or shared-services connectivity.
  • It fits naturally into CI/CD and reusable network modules.
Simple idea: Terraform turns peering from a one-time portal link into a reusable network connectivity blueprint.

Terraform code

This example creates:

  • an Azure resource group
  • two virtual networks
  • one peering from VNet A to VNet B
  • one peering from VNet B to VNet A
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.100"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = var.resource_group_name
  location = var.location
}

resource "azurerm_virtual_network" "hub_vnet" {
  name                = var.hub_vnet_name
  address_space       = ["10.50.0.0/16"]
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_virtual_network" "spoke_vnet" {
  name                = var.spoke_vnet_name
  address_space       = ["10.60.0.0/16"]
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_virtual_network_peering" "hub_to_spoke" {
  name                      = "hub-to-spoke"
  resource_group_name       = azurerm_resource_group.rg.name
  virtual_network_name      = azurerm_virtual_network.hub_vnet.name
  remote_virtual_network_id = azurerm_virtual_network.spoke_vnet.id

  allow_virtual_network_access = true
  allow_forwarded_traffic      = true
  allow_gateway_transit        = false
  use_remote_gateways          = false
}

resource "azurerm_virtual_network_peering" "spoke_to_hub" {
  name                      = "spoke-to-hub"
  resource_group_name       = azurerm_resource_group.rg.name
  virtual_network_name      = azurerm_virtual_network.spoke_vnet.name
  remote_virtual_network_id = azurerm_virtual_network.hub_vnet.id

  allow_virtual_network_access = true
  allow_forwarded_traffic      = true
  allow_gateway_transit        = false
  use_remote_gateways          = false
}

Code breakdown

Virtual network resources

The two VNets must exist before the peering resources can connect them. Their address spaces should not overlap. Azure peering depends on non-overlapping address ranges for correct connectivity. :contentReference[oaicite:3]{index=3}

Peering from each side

Terraform commonly models bidirectional peering using two azurerm_virtual_network_peering resources, one from each VNet side. This mirrors how teams usually configure both directions explicitly. :contentReference[oaicite:4]{index=4}

Remote virtual network ID

This field identifies which VNet the current VNet should peer to. It is one of the most important settings in the resource.

Peering flags

Settings such as forwarded traffic, gateway transit, and remote gateway use shape how the peering behaves beyond simple connectivity.

Why this structure is useful

This example is practical because it shows the most common real-world pattern: two separate peerings, one in each direction, with explicit control over the main peering properties.

Important peering fields

A good VNet Peering Terraform page should explain that peering is not only “connect VNet A and VNet B.” A few settings strongly affect behavior.

Field What it controls Example
remote_virtual_network_id The VNet being peered to spoke VNet resource ID
allow_virtual_network_access Whether private access between VNets is allowed true
allow_forwarded_traffic Whether forwarded traffic can traverse the peering true
allow_gateway_transit Whether this VNet can let the remote VNet use its gateway false
use_remote_gateways Whether this VNet should use a gateway in the remote VNet false
Important reminder: Peering can be created successfully but still not behave as intended if the forwarding or gateway settings do not match the actual design.

Gateway transit settings

Azure peering supports gateway transit, which allows one peered VNet to use a VPN or ExpressRoute gateway in another peered VNet. In hub-and-spoke designs, the hub often enables gateway transit and the spoke enables remote gateway use. :contentReference[oaicite:5]{index=5}

Setting Meaning Typical side
allow_gateway_transit = true This VNet offers its gateway to the remote peered VNet Hub side
use_remote_gateways = true This VNet consumes the gateway from the remote peered VNet Spoke side
Simple idea: The hub offers the gateway, and the spoke uses the remote gateway.

Suggested variables

Variables make peering Terraform code more reusable across development, testing, and production environments.

variable "resource_group_name" {
  description = "Name of the Azure resource group"
  type        = string
}

variable "location" {
  description = "Azure region for deployment"
  type        = string
  default     = "South Africa North"
}

variable "hub_vnet_name" {
  description = "Name of the hub VNet"
  type        = string
}

variable "spoke_vnet_name" {
  description = "Name of the spoke VNet"
  type        = string
}

variable "environment" {
  description = "Environment name"
  type        = string
  default     = "dev"
}

Example terraform.tfvars

resource_group_name = "rg-network-dev-san-1"
location            = "South Africa North"
hub_vnet_name       = "vnet-hub-dev-san-1"
spoke_vnet_name     = "vnet-spoke-dev-san-1"
environment         = "dev"

Suggested outputs

Outputs help expose peering IDs and names for validation or later modules.

output "hub_to_spoke_peering_id" {
  value = azurerm_virtual_network_peering.hub_to_spoke.id
}

output "spoke_to_hub_peering_id" {
  value = azurerm_virtual_network_peering.spoke_to_hub.id
}

output "hub_vnet_id" {
  value = azurerm_virtual_network.hub_vnet.id
}

output "spoke_vnet_id" {
  value = azurerm_virtual_network.spoke_vnet.id
}

How to run it

A simple Terraform execution flow looks like this:

terraform init
terraform fmt
terraform validate
terraform plan
terraform apply

In real teams, these steps often run through CI/CD after review rather than manually every time.

Good habit: Always run terraform fmt and terraform validate before planning or applying changes.

Real-world usage

This peering Terraform pattern can grow into real enterprise network connectivity designs.

Hub-and-spoke platform design

A platform team peers spoke VNets to a central hub VNet containing shared services such as firewalls, Bastion, and gateways.

Cross-subscription connectivity

Application networks in separate subscriptions are peered so workloads can communicate privately without collapsing into one large flat network.

Gateway-sharing pattern

A hub VNet offers gateway transit while spokes use the hub’s remote gateway for hybrid connectivity.

Important mindset: Start with a clear two-VNet peering example, then expand into gateway transit, UDR service chaining, and more advanced cross-region or multi-subscription patterns.

Best practices

  • Plan VNet address spaces carefully and avoid overlap.
  • Use clear peering names that reflect direction and purpose.
  • Document why each peering exists.
  • Be deliberate with forwarded traffic and gateway settings.
  • Keep hub-and-spoke roles clear if that design is used.
  • Validate routes and real traffic behavior after peering is created.
  • Remember that NSGs and UDRs still affect the final connectivity path.
  • Use reusable Terraform modules once peering patterns repeat.
Strong next step: After this peering example, a natural progression is gateway transit, service chaining with UDRs, and broader hub-and-spoke routing design.

Common mistakes

  • Using overlapping VNet address spaces.
  • Creating only one side of the peering when bidirectional design was intended.
  • Misunderstanding gateway transit flags.
  • Ignoring NSG or UDR effects after peering is created.
  • Assuming peering alone replaces broader network design.
  • Hardcoding too much instead of using variables in reusable environments.
Common beginner trap: Just because Terraform created the peering successfully does not mean traffic will flow as intended. Address plans, routes, NSGs, and gateway settings still matter.

Frequently asked questions

What Terraform resource creates Azure VNet peering?

The azurerm_virtual_network_peering resource creates an Azure VNet peering relationship. :contentReference[oaicite:6]{index=6}

Why do Terraform peering examples often use two resources?

Because teams usually configure peering from each VNet side so the relationship is explicit in both directions.

What do allow_gateway_transit and use_remote_gateways do?

They control whether one peered VNet offers its gateway and whether the other peered VNet consumes that remote gateway. Azure documents this as part of gateway transit behavior. :contentReference[oaicite:7]{index=7}

What should I learn after Azure VNet Peering Terraform?

A good next step is gateway transit, service chaining with UDRs, and broader hub-and-spoke routing design.

Summary

Azure VNet Peering Terraform is one of the best practical ways to understand how private network-to-network connectivity becomes infrastructure as code. It teaches you how peering relationships are declared, how gateway settings matter, and how reusable Azure network connectivity patterns are built in real environments.

Official Azure documentation

These official references are useful if you want deeper platform details for Azure VNet peering and the Terraform resource used to create it.