Azure Networking Terraform Guide

Azure ExpressRoute Terraform

This page explains how to deploy Azure ExpressRoute with Terraform using Azure-specific hybrid connectivity patterns, including ExpressRoute circuits, private peering, the Azure-side virtual network gateway, and the final VNet connection. Microsoft’s current quickstart for Terraform uses this exact architecture pattern.

Instead of treating this as only a short code page, this guide explains how ExpressRoute Terraform maps to real enterprise hybrid connectivity design, what engineers usually get wrong around circuits, peerings, and gateways, and how to structure reusable infrastructure as code for serious Azure network architecture.

Main Terraform resources

The core resources are azurerm_express_route_circuit, azurerm_express_route_circuit_peering, azurerm_virtual_network_gateway, and azurerm_virtual_network_gateway_connection.

Best fit

Ideal when you want repeatable private hybrid connectivity between on-premises and Azure virtual networks with a provider-backed ExpressRoute model.

Common challenge

Most mistakes come from misunderstanding that ExpressRoute is not only a circuit resource. Real deployments also depend on peering, gateway sizing, routing, and often FastPath-aware design.

Primary resources Circuit + peering + gateway Terraform models the full Azure-side ExpressRoute path, not just one resource.
Best for Enterprise hybrid connectivity Version-controlled private connectivity between Azure and on-premises networks.
Key building blocks Circuit, peering, VNet gateway Gateway and connection design matter as much as the circuit itself.
Related services VPN Gateway, VNet Peering ExpressRoute fits into broader hybrid and transit network architecture.

What is Azure ExpressRoute Terraform?

Azure ExpressRoute Terraform means defining Azure’s private hybrid connectivity stack as infrastructure as code instead of building it manually in the portal. The current Microsoft quickstart for Terraform creates a complete ExpressRoute setup including a circuit, private peering, a virtual network, an ExpressRoute gateway, and a VNet connection. :contentReference[oaicite:1]{index=1}

In simple terms, Terraform lets you define how your on-premises network privately reaches Azure, while keeping the circuit, peering, gateway, and connection model reusable and reviewable.
Infrastructure as Code Private hybrid connectivity ExpressRoute circuit Private peering Gateway connection Repeatable environments

Why Terraform is used for Azure ExpressRoute

ExpressRoute may look like a network team topic only, but in practice it affects provider-backed connectivity, Azure network architecture, routing, and application dependency paths. Terraform helps engineering teams standardize the Azure-side portion of the design so that VNets, gateways, and circuit connectivity stay consistent across environments and regions. Microsoft’s quickstart explicitly positions Terraform as a way to create the associated infrastructure together, not just the circuit alone. :contentReference[oaicite:2]{index=2}

Consistency

The same ExpressRoute-connected VNet pattern can be deployed across dev, test, and production with controlled naming and configuration.

Reviewability

Engineers can review peering settings, gateway choices, and connection behavior through pull requests before deployment.

Architecture clarity

Terraform forces teams to model the actual connectivity chain instead of hiding important decisions in the portal.

Azure ExpressRoute Terraform explained with the 5 Ws + How

This keeps the page useful for beginners, working engineers, and interview learners who want practical Azure hybrid connectivity understanding.

What

Terraform-based deployment of ExpressRoute connectivity resources using the AzureRM provider.

Why

To manage private hybrid cloud connectivity in a repeatable and reviewable way.

When

Use it when Azure must connect privately to on-premises environments through ExpressRoute rather than only public-internet VPN paths.

Where

Inside Azure resource groups, virtual networks, gateways, and connections that terminate the Azure side of the ExpressRoute design.

Who

DevOps engineers, cloud engineers, network engineers, platform teams, and architects building enterprise hybrid Azure environments.

How

Terraform declares the circuit, the peering, the VNet gateway, and the final VNet connection so Azure can participate in the provider-backed ExpressRoute architecture. :contentReference[oaicite:3]{index=3}

Prerequisites before writing the Terraform

ExpressRoute Terraform design starts with architecture intent. A clean deployment needs more than just Azure resources. It also needs provider coordination, peering location planning, and clarity on whether you are building standard ExpressRoute, Direct, or a Virtual WAN-based pattern. The current Microsoft quickstart covers the classic VNet and gateway style. :contentReference[oaicite:4]{index=4}

Common prerequisites

  • Azure subscription and Terraform AzureRM provider
  • Resource group
  • Virtual network and GatewaySubnet
  • ExpressRoute circuit parameters
  • Provider-side provisioning workflow
  • Private peering address design

Production planning items

  • Circuit bandwidth and SKU selection
  • Gateway SKU sizing
  • Whether FastPath is required
  • Which VNets should connect to the circuit
  • Resiliency and failover model
  • Provider-managed versus self-managed routing responsibility
The biggest prerequisite is not Terraform syntax. It is knowing the real hybrid connectivity target architecture before you start writing the code.

Terraform resource model for Azure ExpressRoute

ExpressRoute Terraform is not a single resource. A functional Azure-side deployment typically includes the circuit, the peering, the virtual network gateway, and the gateway connection. The current quickstart and provider documentation make this layered model clear. :contentReference[oaicite:5]{index=5}

Terraform resource Azure concept Purpose
azurerm_express_route_circuit ExpressRoute circuit Creates the logical ExpressRoute circuit resource in Azure
azurerm_express_route_circuit_peering Private or Microsoft peering Defines routing domain configuration for the circuit
azurerm_virtual_network_gateway ExpressRoute VNet gateway Provides Azure-side gateway termination for the VNet
azurerm_virtual_network_gateway_connection VNet to circuit connection Connects the Azure VNet gateway to the ExpressRoute circuit
GatewaySubnet Gateway subnet Required subnet that hosts the Azure VNet gateway

Recommended code structure

For real projects, do not scatter ExpressRoute logic randomly through files. Even if the circuit seems like “just a network resource,” gateway design, connection logic, and peering settings affect the entire hybrid platform and should live in a clean structure.

terraform/
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars
└── modules/
    └── expressroute/
        ├── main.tf
        ├── variables.tf
        └── outputs.tf

Root module

Connects naming, environment settings, and shared Azure network components.

Reusable child module

Encapsulates circuit, peering, gateway, and connection logic so multiple environments stay consistent.

Variables and outputs

Keep routing, bandwidth, peering ASN values, and gateway references separated from the core resource logic.

Terraform example for Azure ExpressRoute

This example follows the same overall shape as Microsoft’s current quickstart: it creates an ExpressRoute circuit, private peering, a VNet and GatewaySubnet, an ExpressRoute virtual network gateway, and a connection from that gateway to the circuit. :contentReference[oaicite:6]{index=6}

Terraform starter example
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 4.0.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "rg-expressroute-prod-san-1"
  location = "South Africa North"
}

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-er-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  address_space       = ["10.70.0.0/16"]
}

resource "azurerm_subnet" "gateway_subnet" {
  name                 = "GatewaySubnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.70.255.0/27"]
}

resource "azurerm_public_ip" "gateway_pip" {
  name                = "pip-er-gw-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  allocation_method = "Static"
  sku               = "Standard"

  tags = {
    environment = "prod"
    service     = "expressroute-gateway"
    owner       = "platform-team"
  }
}

resource "azurerm_express_route_circuit" "circuit" {
  name                = "erc-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  service_provider_name = "Equinix"
  peering_location      = "Johannesburg"
  bandwidth_in_mbps     = 500

  sku {
    tier   = "Standard"
    family = "MeteredData"
  }

  tags = {
    environment = "prod"
    service     = "expressroute"
    owner       = "platform-team"
  }
}

resource "azurerm_express_route_circuit_peering" "private_peering" {
  peering_type                  = "AzurePrivatePeering"
  express_route_circuit_name    = azurerm_express_route_circuit.circuit.name
  resource_group_name           = azurerm_resource_group.rg.name
  peer_asn                      = 65010
  primary_peer_address_prefix   = "192.168.10.0/30"
  secondary_peer_address_prefix = "192.168.10.4/30"
  vlan_id                       = 200
}

resource "azurerm_virtual_network_gateway" "er_gateway" {
  name                = "vgw-er-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  type     = "ExpressRoute"
  vpn_type = "RouteBased"
  sku      = "ErGw2AZ"

  ip_configuration {
    name                          = "gw-ip-config"
    public_ip_address_id          = azurerm_public_ip.gateway_pip.id
    private_ip_address_allocation = "Dynamic"
    subnet_id                     = azurerm_subnet.gateway_subnet.id
  }

  tags = {
    environment = "prod"
    service     = "expressroute-gateway"
    owner       = "platform-team"
  }
}

resource "azurerm_virtual_network_gateway_connection" "er_connection" {
  name                = "conn-er-prod-san-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  type                       = "ExpressRoute"
  virtual_network_gateway_id = azurerm_virtual_network_gateway.er_gateway.id
  express_route_circuit_id   = azurerm_express_route_circuit.circuit.id

  express_route_gateway_bypass = true

  tags = {
    environment = "prod"
    service     = "expressroute-connection"
    owner       = "platform-team"
  }
}

output "expressroute_circuit_id" {
  value = azurerm_express_route_circuit.circuit.id
}

output "expressroute_service_key" {
  value     = azurerm_express_route_circuit.circuit.service_key
  sensitive = true
}

output "expressroute_gateway_id" {
  value = azurerm_virtual_network_gateway.er_gateway.id
}

Important note about provider-side provisioning

In real deployments, the service key from the circuit is typically used with the connectivity provider to complete the provider-side provisioning workflow. The provider docs and Azure guidance both reflect that the Azure circuit resource is one part of the full ExpressRoute activation process. :contentReference[oaicite:7]{index=7}

How the Terraform code maps to the real Azure service

Many engineers can paste Terraform, but not everyone understands how each resource changes Azure behavior. This section makes the mapping clear.

Circuit resource

azurerm_express_route_circuit creates the Azure-side logical ExpressRoute circuit and defines provider, peering location, bandwidth, and SKU choices.

Private peering

azurerm_express_route_circuit_peering adds the routing domain that lets Azure private network routes be exchanged for VNet connectivity.

Gateway subnet

The GatewaySubnet hosts the ExpressRoute virtual network gateway, which is why it has a reserved and explicit subnet name in Azure networking.

VNet gateway

azurerm_virtual_network_gateway with type = "ExpressRoute" creates the Azure-side gateway that connects the VNet to the circuit.

Gateway connection

azurerm_virtual_network_gateway_connection ties the VNet gateway to the ExpressRoute circuit and is where gateway-bypass-related connection behavior can be configured. :contentReference[oaicite:8]{index=8}

Service key output

The service key output is operationally important because it is part of how the ExpressRoute circuit is associated with the provider side.

Private peering in Terraform

ExpressRoute peering is one of the most important parts of the Terraform model because it defines the routing domain used by the circuit. Microsoft’s current quickstart focuses on private peering, which is the most important peering for classic Azure VNet connectivity scenarios. :contentReference[oaicite:9]{index=9}

Why private peering matters

It is the peering that usually matters most when the goal is connecting on-premises private networks to Azure VNets and workloads behind them.

What the Terraform fields represent

ASN, VLAN ID, and primary and secondary peer address prefixes are all part of the routing and adjacency design that sits underneath the Azure resource model.

The circuit by itself does not give you useful Azure private routing. The peering configuration is what turns the circuit into a routing-capable hybrid connection.

Gateway and connection model

ExpressRoute Azure-side connectivity often depends on the VNet gateway and the gateway connection. Microsoft’s current gateway guidance and FAQs make clear that gateway choice affects behavior and throughput, so this is not just “extra plumbing.” :contentReference[oaicite:10]{index=10}

On-Prem Network
      |
      v
+-----------------------------------+
| ExpressRoute Circuit              |
| Private Peering                   |
+-----------------------------------+
                 |
                 v
+-----------------------------------+
| Azure VNet Gateway                |
| type = ExpressRoute               |
+-----------------------------------+
                 |
                 v
+-----------------------------------+
| Azure Virtual Network             |
| Workloads / Subnets / Services    |
+-----------------------------------+

Why gateway SKU matters

Gateway type and SKU influence throughput expectations, feature behavior, and how well the Azure side of the design scales with circuit capacity.

Why the connection resource matters

The connection resource expresses the actual relationship between the circuit and the VNet gateway. Without it, Azure-side VNet connectivity is incomplete.

FastPath and gateway bypass

Azure’s current data source documentation for virtual network gateway connections still documents express_route_gateway_bypass as valid only for ExpressRoute connections, and Microsoft’s FastPath guidance explains the performance reason behind bypass-oriented traffic design. This is one of the more advanced but high-value parts of real ExpressRoute architecture. :contentReference[oaicite:11]{index=11}

Why FastPath-related design matters

It changes how traffic traverses the Azure-side path and can matter a lot for performance-sensitive enterprise hybrid designs.

Why this belongs in Terraform thinking

It is not just a conceptual architecture topic. The connection settings and gateway model in code should reflect whether bypass-oriented behavior is part of the design.

One common mistake is to size the circuit carefully and then ignore whether the Azure-side gateway and connection design will actually let the architecture benefit from that planning.

Real-world Azure ExpressRoute Terraform use cases

Practical examples make this page useful and avoid generic Terraform content by grounding ExpressRoute in real hybrid Azure scenarios.

Enterprise private Azure landing zone

A platform team uses Terraform to build a hub VNet with an ExpressRoute gateway so application VNets can consume private hybrid connectivity in a standard pattern.

Banking or telecom hybrid infrastructure

A regulated organization provisions ExpressRoute-connected Azure environments where network control, private routing, and predictable governance matter more than simple VPN cost savings.

Migration platform backbone

A large migration program uses Terraform to keep circuit-connected VNets and gateway patterns consistent while workloads move from on-premises into Azure in phases.

Terraform vs manual Azure portal deployment

Both approaches can work, but Terraform becomes more valuable as hybrid network architecture grows and must remain consistent across environments and teams.

Approach Best for Strength Weakness
Terraform Repeatable production deployments Version control, consistency, reviewable changes Requires structure and code discipline
Azure Portal One-off testing or learning Fast for initial exploration Hard to reproduce accurately across environments
A strong engineering pattern is to understand ExpressRoute once in the portal, then move the final design into Terraform so hybrid connectivity is managed as code instead of remembered as portal steps.

Best practices

Practical guidance is what turns a Terraform page from a snippet page into a real engineering reference.

Design the whole chain, not one resource

Model the circuit, peering, gateway, and connection together so the architecture is complete and reviewable.

Choose gateway SKU deliberately

Do not treat the Azure gateway as a default afterthought when it can become a real architecture and performance boundary.

Keep peering settings explicit

ASN, VLAN, and peer prefixes are core design values and should be treated as deliberate network parameters, not copy-paste leftovers.

Output the service key carefully

It is often needed operationally for provider-side workflow, so treat it as sensitive data.

Document routing ownership

Be clear on what the connectivity provider handles and what your team must manage on the Azure and enterprise-routing side.

Design for failover

Terraform should support resilient hybrid architecture rather than only the happy-path single-connection deployment.

Common mistakes

Platform-specific mistakes are what make this page practical instead of generic. These are the things teams commonly get wrong with ExpressRoute Terraform.

Treating the circuit as the full solution

Engineers sometimes create the circuit and stop there, forgetting that peering, gateway, and connection resources are what make Azure VNet connectivity actually work.

Undersizing the gateway

Teams focus on circuit bandwidth and ignore the Azure-side gateway characteristics that influence the real data path.

Weak peering parameter hygiene

Copying ASN, VLAN, or peer addresses blindly between environments is a common way to create hard-to-debug network problems.

No provider workflow alignment

The Azure resources may exist while the provider-side provisioning is still incomplete, leading teams to troubleshoot the wrong layer.

Ignoring bypass-oriented design

Some teams never revisit the connection model to see whether FastPath-related behavior should be part of the architecture.

No DR thinking in code

Hybrid connectivity is business-critical, so single-path Terraform without resilience planning is often not enough for production.

Frequently asked questions

FAQ sections help capture real search intent and make the page more complete for working engineers and learners.

What Terraform resource creates an ExpressRoute circuit?

The main circuit resource is azurerm_express_route_circuit. :contentReference[oaicite:12]{index=12}

What Terraform resource creates ExpressRoute peering?

Use azurerm_express_route_circuit_peering to define the circuit peering such as Azure private peering. :contentReference[oaicite:13]{index=13}

How do I connect a VNet to an ExpressRoute circuit in Terraform?

The usual Azure-side pattern is an ExpressRoute virtual network gateway plus an azurerm_virtual_network_gateway_connection that references the circuit. :contentReference[oaicite:14]{index=14}

Is gateway bypass only for ExpressRoute?

Azure’s current documentation for gateway connection data still documents express_route_gateway_bypass as valid only for ExpressRoute connections. :contentReference[oaicite:15]{index=15}

Does Microsoft have a Terraform quickstart for ExpressRoute plus VNet?

Yes. Microsoft’s current quickstart explicitly shows creating an ExpressRoute circuit and virtual network with Terraform. :contentReference[oaicite:16]{index=16}

Can ExpressRoute also be part of Virtual WAN?

Yes, but that is a different architecture pattern from the classic VNet gateway style shown here. Microsoft has a separate tutorial for ExpressRoute with Virtual WAN. :contentReference[oaicite:17]{index=17}