At some point, you might need to extend the address space of an existing virtual network that’s peered with your connectivity landing zone (Hub). Let’s assume you’re starting with the following configuration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
resource "azurerm_resource_group" "example" { name = "rg-weu-vnet-peering-test" location = "westeurope" } resource "azurerm_virtual_network" "example-1" { name = "vnet-weu-hub-001" resource_group_name = azurerm_resource_group.example.name address_space = ["10.0.1.0/24"] location = "westeurope" } resource "azurerm_virtual_network" "example-2" { name = "vnet-weu-spoke-001" resource_group_name = azurerm_resource_group.example.name address_space = ["10.0.3.0/24"] location = "westeurope" } resource "azurerm_virtual_network_peering" "example-1" { name = "peerhubtospoke" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example-1.name remote_virtual_network_id = azurerm_virtual_network.example-2.id } resource "azurerm_virtual_network_peering" "example-2" { name = "peerspoketohub" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example-2.name remote_virtual_network_id = azurerm_virtual_network.example-1.id } |
The initial thought might be to simply extend the address space of the spoke network by adding another CIDR block, like “10.0.4.0/24,” to the “address_space” parameter.
1 2 3 4 5 6 |
resource "azurerm_virtual_network" "example-2" { name = "vnet-weu-spoke-001" resource_group_name = azurerm_resource_group.example.name address_space = ["10.0.3.0/24", "10.0.4.0/24"] location = "westeurope" } |
After applying the configuration change, you might notice an issue with your Virtual Network peering when you check the peering status in the Azure Portal. The peering sync status will indicate that a “Remote Sync” is required to make the new address space available to the connected peer.
At this point, communication will still work for the previously existing address space, but you won’t be able to reach Virtual Machines, Private Endpoints, or other services assigned an IP address from the new network range. Since we avoid using “ClickOps” for infrastructure provisioning, the “Sync” button in the Azure Portal isn’t an option. How can we fix the peering status without using that portal function?
One approach could be to use the Terraform lifecycle
meta-argument, but this method has a significant drawback. First, let’s take a look at the Terraform configuration if we decide to go down this path.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
resource "azurerm_resource_group" "example" { name = "rg-weu-vnet-peering-test" location = "westeurope" } resource "azurerm_virtual_network" "example-1" { name = "vnet-weu-hub-001" resource_group_name = azurerm_resource_group.example.name address_space = ["10.0.1.0/24"] location = "westeurope" } resource "azurerm_virtual_network" "example-2" { name = "vnet-weu-spoke-001" resource_group_name = azurerm_resource_group.example.name address_space = ["10.0.3.0/24", "10.0.40.0/24"] location = "westeurope" } resource "azurerm_virtual_network_peering" "example-1" { name = "peerhubtospoke" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example-1.name remote_virtual_network_id = azurerm_virtual_network.example-2.id lifecycle { replace_triggered_by = [azurerm_virtual_network.example-1.address_space, azurerm_virtual_network.example-2.address_space] } } resource "azurerm_virtual_network_peering" "example-2" { name = "peerspoketohub" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example-2.name remote_virtual_network_id = azurerm_virtual_network.example-1.id lifecycle { replace_triggered_by = [azurerm_virtual_network.example-1.address_space, azurerm_virtual_network.example-2.address_space] } } |
As you can see, during the plan or apply stage, Terraform indicates that the peering must be replaced. This means the existing peering would be destroyed and then recreated, which would disrupt our entire network stack and cause a downtime for our service —something we absolutely want to avoid.
There must be a better way, right? Indeed, with version 3.47.0 (released in March 2023) of the “hashicorp/azurerm” Terraform provider, a new “triggers” property was introduced. This feature allows us to update the address spaces without having to recreate the peering for the affected virtual networks, thus avoiding any downtime. Here’s the recommended approach for extending the address space of a virtual network.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
resource "azurerm_resource_group" "example" { name = "rg-weu-vnet-peering-test" location = "westeurope" } resource "azurerm_virtual_network" "example-1" { name = "vnet-weu-hub-001" resource_group_name = azurerm_resource_group.example.name address_space = ["10.0.1.0/24"] location = "westeurope" } resource "azurerm_virtual_network" "example-2" { name = "vnet-weu-spoke-001" resource_group_name = azurerm_resource_group.example.name address_space = ["10.0.3.0/24", "10.0.4.0/24"] location = "westeurope" } resource "azurerm_virtual_network_peering" "example-1" { name = "peerhubtospoke" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example-1.name remote_virtual_network_id = azurerm_virtual_network.example-2.id triggers = { remote_address_space = join(",", azurerm_virtual_network.example-2.address_space) } } resource "azurerm_virtual_network_peering" "example-2" { name = "peerspoketohub" resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example-2.name remote_virtual_network_id = azurerm_virtual_network.example-1.id triggers = { remote_address_space = join(",", azurerm_virtual_network.example-1.address_space) } } |