
Deploying Hub and Spoke Network Architecture in Azure Using Terraform for Contoso.com
Organizations moving to the cloud often need a secure and scalable network architecture that allows multiple workloads to communicate safely while maintaining centralized control over connectivity and security. One of the most commonly used network architectures in Microsoft Azure is the Hub and Spoke model.
In this article, we will walk through a real-world style scenario for Contoso.com and demonstrate how to deploy a Hub and Spoke architecture using Terraform. The deployment will include a hub virtual network that hosts shared services and multiple spoke networks that host application workloads.
This approach enables centralized security, simplified routing, and scalable network design while using Infrastructure as Code to automate deployment.
Scenario Overview
Contoso.com is a global company that is migrating several internal applications to Microsoft Azure. Their infrastructure team has decided to implement a Hub and Spoke architecture to separate networking responsibilities and maintain centralized control over connectivity and security.
Contoso has the following requirements.
Centralized security inspection through the hub network
Application isolation across multiple spokes
Centralized VPN connectivity for on-premises users
Shared services such as DNS and monitoring located in the hub
Automated deployment using Terraform
Architecture Design
The hub network will contain shared infrastructure services:
- Hub Components
- Azure Firewall
- VPN Gateway
- Shared DNS
- Management services
Each application environment will reside in its own spoke virtual network.
Spoke Networks:
- Application Spoke
- Database Spoke
- Development Spoke
All spoke networks will connect to the hub network using VNet peering.
High-Level Network Layout
Hub VNet
10.0.0.0/16
Application Spoke
10.1.0.0/16
Database Spoke
10.2.0.0/16
Development Spoke
10.3.0.0/16
All spokes communicate through the hub network where security and routing policies are enforced.
Prerequisites:
Before deploying this architecture using Terraform, the following requirements must be satisfied:
- Azure subscription
- Terraform installed
- Azure CLI installed
Proper permissions to create networking resources
Login to Azure: az login
Terraform Deployment Structure
A typical Terraform project for this deployment would follow a modular structure.
terraform-hub-spoke-contoso
main.tf
variables.tf
outputs.tf
This keeps the configuration organized and maintainable.
Terraform Provider Configuration
The Azure provider must be configured so Terraform can interact with Azure resources.
provider "azurerm" {
features {}
}
Create Resource Group
The first step is creating a resource group to contain the networking resources.
resource "azurerm_resource_group" "contoso_network" {
name = "rg-contoso-network"
location = "East US"
}
Create Hub Virtual Network
The hub network hosts shared infrastructure services such as firewalls and VPN gateways.
resource "azurerm_virtual_network" "hub_vnet" {
name = "vnet-contoso-hub"
location = azurerm_resource_group.contoso_network.location
resource_group_name = azurerm_resource_group.contoso_network.name
address_space = ["10.0.0.0/16"]
}
Create Hub Subnets
The hub network requires subnets for shared services.
resource "azurerm_subnet" "hub_firewall" {
name = "AzureFirewallSubnet"
resource_group_name = azurerm_resource_group.contoso_network.name
virtual_network_name = azurerm_virtual_network.hub_vnet.name
address_prefixes = ["10.0.1.0/24"]
}
resource "azurerm_subnet" "hub_management" {
name = "ManagementSubnet"
resource_group_name = azurerm_resource_group.contoso_network.name
virtual_network_name = azurerm_virtual_network.hub_vnet.name
address_prefixes = ["10.0.2.0/24"]
}
Create Spoke Virtual Networks
Contoso deploys three spokes to isolate workloads.
Application Spoke
resource "azurerm_virtual_network" "app_spoke" {
name = "vnet-contoso-app"
location = azurerm_resource_group.contoso_network.location
resource_group_name = azurerm_resource_group.contoso_network.name
address_space = ["10.1.0.0/16"]
}
Database Spoke
resource "azurerm_virtual_network" "db_spoke" {
name = "vnet-contoso-db"
location = azurerm_resource_group.contoso_network.location
resource_group_name = azurerm_resource_group.contoso_network.name
address_space = ["10.2.0.0/16"]
}
Development Spoke
resource "azurerm_virtual_network" "dev_spoke" {
name = "vnet-contoso-dev"
location = azurerm_resource_group.contoso_network.location
resource_group_name = azurerm_resource_group.contoso_network.name
address_space = ["10.3.0.0/16"]
}
Create Spoke Subnets
Application subnet
resource "azurerm_subnet" "app_subnet" {
name = "app-subnet"
resource_group_name = azurerm_resource_group.contoso_network.name
virtual_network_name = azurerm_virtual_network.app_spoke.name
address_prefixes = ["10.1.1.0/24"]
}
Database Subnet
resource "azurerm_subnet" "db_subnet" {
name = "db-subnet"
resource_group_name = azurerm_resource_group.contoso_network.name
virtual_network_name = azurerm_virtual_network.db_spoke.name
address_prefixes = ["10.2.1.0/24"]
}
Development Subnet
resource "azurerm_subnet" "dev_subnet" {
name = "dev-subnet"
resource_group_name = azurerm_resource_group.contoso_network.name
virtual_network_name = azurerm_virtual_network.dev_spoke.name
address_prefixes = ["10.3.1.0/24"]
}
Create VNet Peering Connections
Spoke networks must connect to the hub network.
Application Spoke to Hub
resource "azurerm_virtual_network_peering" "app_to_hub" {
name = "app-hub-peer"
resource_group_name = azurerm_resource_group.contoso_network.name
virtual_network_name = azurerm_virtual_network.app_spoke.name
remote_virtual_network_id = azurerm_virtual_network.hub_vnet.id
}
Hub to Application Spoke
resource "azurerm_virtual_network_peering" "hub_to_app" {
name = "hub-app-peer"
resource_group_name = azurerm_resource_group.contoso_network.name
virtual_network_name = azurerm_virtual_network.hub_vnet.name
remote_virtual_network_id = azurerm_virtual_network.app_spoke.id
}
Repeat this process for database and development spokes.
Terraform Deployment Steps
After writing the Terraform configuration files, deployment follows the typical Terraform workflow.
Initialize Terraform
terraform init
Validate configuration
terraform validate
Review execution plan
terraform plan
Deploy infrastructure
terraform apply
Terraform will provision the hub network, spokes, and peering connections automatically.
Network Flow in the Contoso Architecture
Traffic from application workloads in spoke networks flows through the hub network where centralized services can inspect or route traffic.
Application VM
Application Spoke Network
Hub Network
Azure Firewall
External Network or On-Premises
This architecture allows centralized control and simplified network management.
Best Practices for Hub and Spoke Architecture
Use centralized security controls in the hub network
Implement Azure Firewall or Network Virtual Appliances
Use route tables to control traffic flow
Separate production and development workloads
Use Terraform modules for reusable network architecture
Benefits for Contoso
Centralized security management
Scalable application network isolation
Simplified hybrid connectivity
Automated infrastructure deployment
Consistent cloud networking architecture
Conclusion
The Hub and Spoke network architecture is a proven design pattern for large Azure environments. By using Terraform, Contoso.com can automate the deployment of secure, scalable network infrastructure while maintaining consistency across environments.
Infrastructure as Code allows the entire architecture to be version-controlled, repeatable, and easily maintained. As organizations expand their cloud footprint, Terraform-based network automation becomes a critical component of enterprise cloud governance.
For readers who want a deeper understanding of Terraform architecture, Infrastructure as Code design, module development, and enterprise automation strategies, refer to my book Mastering Terraform: A Comprehensive Guide to Infrastructure as Code, which expands on the concepts discussed in this article with detailed technical examples and real-world implementations.
0 comments