Hello and welcome to my next blog in my Terraform series. In this blog I’ll show you how you can deploy a hub-spoke virtual network with the following components:
- Hub vnet
- 3 spoke vnets (Prod, Dev and Test)
- Hub subnets for Firewall, Vpn and Bastion
- Peerings between the Hub and Spokes
- Nsg’s for all vnets
- Diagnostic settings enabled for all resources to Log Analytics Workspace in the hub
Import Log Analytics Workspace
Because I want to send the logs to the Log Analytics Workspace I need to start with importing the resource in my Terraform file.
data "azurerm_log_analytics_workspace" "law" {
name = "law-hub-jvn-01"
resource_group_name = "rg-hub-jvn-law-01"
}
Deploy the Vnet Resource groups
First we need the resource groups for the vnets Hub, Prod, Dev and Test. The below example is for the hub resource groups. the rest of the examples will also be for the Hub vnet. The rest of the code will be available on my github repo.
resource "azurerm_resource_group" "vnet-hub-rg" {
name = "rg-hub-${var.prefix}-vnet-01"
location = var.location
tags = {
"Critical" = "Yes"
"Solution" = "Vnet"
"Costcenter" = "It"
"Environment" = "Hub"
"Location" = "Weu"
}
}
Deploy the Hub Vnet
Now that we have the resource groups it’s time to create the vnets. The example below is for the Hub vnet.
resource "azurerm_virtual_network" "hub-vnet" {
name = "vnet-hub-${var.prefix}-weu-01"
location = var.location
resource_group_name = azurerm_resource_group.vnet-hub-rg.name
address_space = ["10.0.0.0/20"]
dns_servers = ["10.5.0.4","168.63.129.16"]
tags = {
"Critical" = "Yes"
"Solution" = "Vnet"
"Costcenter" = "It"
"Environment" = "Hub"
"Location" = "Weu"
}
}
Deploy the NSG’s
The next piece of code that we need if for the nsg. In this example rule I put a “deny” on port 3389.
resource "azurerm_network_security_group" "nsg-hub" {
name = "nsg-hub-${var.prefix}-01"
location = azurerm_resource_group.vnet-hub-rg.location
resource_group_name = azurerm_resource_group.vnet-hub-rg.name
security_rule {
name = "allow-rdp"
priority = 100
direction = "Inbound"
access = "Deny"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = 3389
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
Deploy the Network Watcher
The next resource that I will deploy is the Network Watcher. Azure Network Watcher provides tools to monitor, diagnose, view metrics, and enable or disable logs for resources in an Azure virtual network.
resource "azurerm_network_watcher" "network-watcher-hub" {
name = "nw-${var.prefix}-vnet-we-01"
location = azurerm_resource_group.vnet-hub-rg.location
resource_group_name = azurerm_resource_group.vnet-hub-rg.name
tags = {
"Critical" = "Yes"
"Solution" = "Vnet"
"Costcenter" = "It"
"Location" = "Weu"
}
}
Deploy the Hub subnets
Now that we have the Hub vnet we can deploy some of the subnets that belong in there. I’ll give 1 example below, the rest is on my Github page.
resource "azurerm_subnet" "firewall-subnet" {
name = "AzureFirewallSubnet" ##can also be AzureFirewallManagementSubnet
resource_group_name = azurerm_resource_group.vnet-hub-rg.name
virtual_network_name = azurerm_virtual_network.hub-vnet.name
address_prefixes = ["10.0.5.0/26"]
}
Deploy the Spoke Vnets
Now that we have the Hub vnet and the Hub subnets it’s time to create the Spoke Vnets. Again I’ll give 1 example and the rest is on Github.
resource "azurerm_virtual_network" "prod-vnet" {
name = "vnet-prod-${var.prefix}-weu-01"
location = var.location
resource_group_name = azurerm_resource_group.vnet-prod-rg.name
address_space = ["10.1.0.0/20"]
dns_servers = ["10.5.0.4","168.63.129.16"]
tags = {
"Critical" = "Yes"
"Solution" = "Vnet"
"Costcenter" = "It"
"Environment" = "Prod"
"Location" = "Weu"
}
}
Vnet peering between hub and spoke
When deploying a hub and spoke network topology you also need to deploy vnet peering. The below example is the peering between the Hub and Prod spoke.
resource "azurerm_virtual_network_peering" "peer-hub-2-prod" {
name = "peer-hub-2-prod"
resource_group_name = azurerm_resource_group.vnet-hub-rg.name
virtual_network_name = azurerm_virtual_network.hub-vnet.name
remote_virtual_network_id = azurerm_virtual_network.prod-vnet.id
}
resource "azurerm_virtual_network_peering" "peer-prod-2-hub" {
name = "peer-prod-2-hub"
resource_group_name = azurerm_resource_group.vnet-prod-rg.name
virtual_network_name = azurerm_virtual_network.prod-vnet.name
remote_virtual_network_id = azurerm_virtual_network.hub-vnet.id
}
Diagnostic settings on vnet and nsg
Each resource in Azure has it’s own set of diagnostic settings that you can configure. In this example I configure the diagnostic settings for the hub vnet and nsg. I enable them to be sent to the central log analytics workspace.
resource "azurerm_monitor_diagnostic_setting" "nsg-Hub" {
name = "diag-hub-${var.prefix}-nsg"
target_resource_id = azurerm_network_security_group.nsg-hub.id
log_analytics_workspace_id = data.azurerm_log_analytics_workspace.law.id
depends_on = [azurerm_network_security_group.nsg-hub]
log {
category = "NetworkSecurityGroupEvent"
enabled = true
retention_policy {
enabled = true
}
}
log {
category = "NetworkSecurityGroupRuleCounter"
enabled = true
retention_policy {
enabled =true
}
}
}
--------------------------------------------------
resource "azurerm_monitor_diagnostic_setting" "vnet-hub-diag" {
name = "diag-hub-${var.prefix}-vnet"
target_resource_id = azurerm_virtual_network.hub-vnet.id
log_analytics_workspace_id = data.azurerm_log_analytics_workspace.law.id
depends_on = [azurerm_virtual_network.hub-vnet]
log {
category = "VMProtectionAlerts"
}
metric {
category = "AllMetrics"
retention_policy {
enabled = true
}
}
}
I hope this code can be useful for you to deploy your Hub-Spoke virtual network in Azure. If you have any questions about this feel free to contact me on Linkedin or via my Twitter handle.