Quick summary
Before going deeper, here is the simplest way to think about Azure Route Tables Terraform.
azurerm_route_table and usually azurerm_route.
Why use Terraform for Azure Route Tables?
Route tables can be created manually in the Azure portal, but Terraform is better when you need standardization, reviewable routing logic, repeatable deployments, and consistent multi-environment infrastructure.
- It keeps routing logic in code instead of clicks.
- It makes route changes visible in Git and code review.
- It reduces manual mistakes with prefixes and next hop settings.
- It helps platform teams deploy consistent routing patterns across environments.
- It fits naturally into CI/CD and reusable networking modules.
Terraform code
This example creates:
- an Azure resource group
- one Azure Route Table
- two custom routes inside that route table
terraform {
required_version = ">= 1.5.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.100"
}
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "network_rg" {
name = var.resource_group_name
location = var.location
}
resource "azurerm_route_table" "app_routes" {
name = var.route_table_name
location = azurerm_resource_group.network_rg.location
resource_group_name = azurerm_resource_group.network_rg.name
tags = {
environment = var.environment
managed_by = "terraform"
purpose = "routing-control"
}
}
resource "azurerm_route" "default_to_firewall" {
name = "default-to-firewall"
resource_group_name = azurerm_resource_group.network_rg.name
route_table_name = azurerm_route_table.app_routes.name
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = "10.20.0.4"
}
resource "azurerm_route" "onprem_via_gateway" {
name = "onprem-via-gateway"
resource_group_name = azurerm_resource_group.network_rg.name
route_table_name = azurerm_route_table.app_routes.name
address_prefix = "172.16.0.0/16"
next_hop_type = "VirtualNetworkGateway"
}
Code breakdown
Terraform block
This defines the Terraform version and AzureRM provider version. Provider version pinning helps avoid unexpected changes during later deployments.
Provider block
The AzureRM provider is what Terraform uses to communicate with Azure and manage resources.
Resource group
Azure resources need a resource group, so this is usually one of the first resources created.
Route table resource
The azurerm_route_table resource creates the route table container itself. The actual traffic direction behavior comes from the routes placed inside it.
Route resources
The azurerm_route resources define the destination prefix and the next hop Azure should use for matching traffic.
Why separate route resources are useful
Many teams prefer separate route resources because they are easier to review, understand, and maintain than large inline route definitions.
Important route fields in Terraform
A good Azure Route Tables Terraform page should explain that routes are really traffic-matching instructions, not just named entries.
| Field | What it controls | Example |
|---|---|---|
| address_prefix | The destination range the route should match | 0.0.0.0/0, 172.16.0.0/16 |
| next_hop_type | Where Azure should send matching traffic next | VirtualAppliance, VirtualNetworkGateway, Internet |
| next_hop_in_ip_address | The next hop IP when using a virtual appliance | 10.20.0.4 |
| route_table_name | The route table that contains the route | rt-app-dev-san-1 |
Next hop types explained
The next hop type is one of the most important parts of route design because it tells Azure what to do with matching traffic.
| Next hop type | Meaning | Typical use |
|---|---|---|
| VirtualAppliance | Send traffic to a firewall or network appliance | Forced inspection, centralized egress |
| VirtualNetworkGateway | Send traffic toward VPN or ExpressRoute connectivity | Hybrid traffic paths |
| Internet | Send traffic toward the internet | Custom outbound behavior |
| VnetLocal | Keep traffic inside the virtual network | Local Azure traffic behavior |
| None | Drop or black-hole matching traffic | Deliberate block of specific paths |
Suggested variables file
Variables make Route Table 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 "route_table_name" {
description = "Name of the Azure Route Table"
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"
route_table_name = "rt-app-dev-san-1"
environment = "dev"
Suggested outputs
Outputs help expose route table IDs and names so they can be used by subnet association resources or downstream modules.
output "route_table_name" {
value = azurerm_route_table.app_routes.name
}
output "route_table_id" {
value = azurerm_route_table.app_routes.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.
terraform fmt and terraform validate before planning or applying changes.
Real-world usage
This Route Table Terraform pattern can grow naturally into real enterprise routing workflows.
Forced tunneling through firewall
A team uses a default route with next hop type VirtualAppliance so all outbound traffic from a subnet is inspected by a central firewall.
Hybrid routing to on-premises
Traffic destined for datacenter ranges is sent through a virtual network gateway instead of following internet-facing paths.
Hub-and-spoke network design
Spoke subnet route tables direct traffic toward centralized services in the hub for control, logging, or inspection.
Best practices
- Use clear route table and route names.
- Keep destination prefixes specific and intentional.
- Understand exactly why each next hop is chosen.
- Document route purpose, not just the route itself.
- Test route logic in non-production before broad rollout.
- Be very careful with default routes like
0.0.0.0/0. - Keep route design aligned with subnet and security architecture.
- Separate routing logic from traffic filtering logic in your thinking and code.
Common mistakes
- Using the wrong address prefix so the route never matches.
- Choosing the wrong next hop type for the design.
- Forgetting to associate the route table with the intended subnet.
- Using default routes too broadly without understanding the impact.
- Assuming route tables filter traffic like NSGs do.
- Hardcoding values without variables in reusable environments.
Frequently asked questions
What Terraform resource creates an Azure Route Table?
The azurerm_route_table resource creates an Azure Route Table.
What Terraform resource creates an individual route?
The azurerm_route resource creates an individual custom route inside a route table.
Should I create routes inline or separately?
For small examples either can work, but many teams prefer separate route resources for readability and easier review.
What should I learn after Azure Route Tables Terraform?
A good next step is subnet association, firewall next hop patterns, hub-and-spoke routing, and more advanced forced tunneling designs.
Summary
Azure Route Tables Terraform is one of the best practical ways to understand how Azure traffic direction becomes infrastructure as code. It teaches you how custom routes are expressed, how prefixes and next hops interact, and how reusable routing foundations are built in real Azure environments.
Official Azure documentation
These official references are useful if you want deeper platform details for Azure Route Tables and the Terraform resources used to create them.