Terraform GCP Azure site-to-site VPN
Hey in this blog post I will present the recipe for creating a static route site-to-site vpn between GCP and Azure using Terraform.
!Disclaimer I am not following any kind of best practice my only goal was to create a working Site-to-site VPN connection between a GCP and Azure - so please don’t think that this is a production ready example!
The main catch I got out of this is that if you need a connection that is bi-directional you must create a gateway on each site you want to connect and also to create connections for each one - the recomended number of connections is 2 but in the example for the sake of saving some pennies I used just a connection.
- Public ip GCP
- Google compute vpn gateway
- Loose forwarding rules
- Google compute vpn tunnel
- Google compute route
GCP
Public ip GCP
resource "google_compute_address" "gcp_vpn_ip" {
name = "gcp_vpn_ip"
region = "${var.gcp_region}"
}
Google compute vpn gateway
resource "google_compute_vpn_gateway" "gcp_vpn_gateway" {
name = "gcp_vpn_gateway"
network = "${google_compute_network.gcp_network.name}"
region = "${var.gcp_region}"
}
Loose forwarding rules
resource "google_compute_forwarding_rule" "fr_esp" {
name = "fr_esp"
ip_protocol = "ESP"
ip_address = "${google_compute_address.gcp_vpn_ip.address}"
target = "${google_compute_vpn_gateway.gcp_vpn_gateway.self_link}"
}
resource "google_compute_forwarding_rule" "fr_udp500" {
name = "fr_udp500"
ip_protocol = "UDP"
port_range = "500_500"
ip_address = "${google_compute_address.gcp_vpn_ip.address}"
target = "${google_compute_vpn_gateway.gcp_vpn_gateway.self_link}"
}
resource "google_compute_forwarding_rule" "fr_udp4500" {
name = "fr_udp4500"
ip_protocol = "UDP"
port_range = "4500_4500"
ip_address = "${google_compute_address.gcp_vpn_ip.address}"
target = "${google_compute_vpn_gateway.gcp_vpn_gateway.self_link}"
}
Google compute vpn tunnel
resource "google_compute_vpn_tunnel" "gcp_vpn_tunnel" {
name = "gcp_vpn_tunnel"
peer_ip = "${data.azurerm_public_ip.vpn_ipv4.ip_address}"
ike_version = 2
shared_secret = "123456789"
target_vpn_gateway = "${google_compute_vpn_gateway.gcp_vpn_gateway.self_link}"
local_traffic_selector = ["${var.gcp_vpc_range}"]
remote_traffic_selector = ["${var.azure_vpc_range}"]
depends_on = [
"google_compute_forwarding_rule.fr_esp",
"google_compute_forwarding_rule.fr_udp500",
"google_compute_forwarding_rule.fr_udp4500",
"data.azurerm_public_ip.vpn_ipv4",
]
}
Google compute route
resource "google_compute_route" "azure_route" {
name = "azure_route"
dest_range = "${var.azure_vpc_range}"
network = "${google_compute_network.gcp_network.self_link}"
next_hop_vpn_tunnel = "${google_compute_vpn_tunnel.gcp_vpn_tunnel.self_link}"
priority = 100
depends_on = [
"google_compute_vpn_tunnel.gcp_vpn_tunnel"
]
}
Azure
Public ip Azure
resource "azurerm_public_ip" "vpn_ipv4" {
name = "vpn_ipv4"
location = "${azurerm_resource_group.resource_group_1.location}"
resource_group_name = "${azurerm_resource_group.resource_group_1.name}"
allocation_method = "Dynamic"
}
data "azurerm_public_ip" "vpn_ipv4" {
name = "vpn_ipv4"
resource_group_name = "${azurerm_resource_group.resource_group_1.name}"
depends_on = [
"azurerm_virtual_network_gateway.az_vnet_gw"
]
}
Local network gateway
resource "azurerm_local_network_gateway" "gcp_local_vnet_gw" {
name = "gcp_local_vnet_gw"
location = "${azurerm_resource_group.resource_group_1.location}"
resource_group_name = "${azurerm_resource_group.resource_group_1.name}"
gateway_address = "${google_compute_address.gcp_vpn_ip.address}"
address_space = ["${var.gcp_vpc_range}"]
}
Virtual network gateway
resource "azurerm_virtual_network_gateway" "az_vnet_gw" {
name = "az_vnet_gw"
location = "${azurerm_resource_group.resource_group_1.location}"
resource_group_name = "${azurerm_resource_group.resource_group_1.name}"
type = "vpn"
vpn_type = "RouteBased"
active_active = false
enable_bgp = false
sku = "HighPerformance"
ip_configuration {
name = "vnetGatewayConfig"
public_ip_address_id = "${azurerm_public_ip.vpn_ipv4.id}"
private_ip_address_allocation = "Dynamic"
subnet_id = "${azurerm_subnet.mygwsubnet.id}"
}
}
Virtual network gateway connection
resource "azurerm_virtual_network_gateway_connection" "gcp_gw_conn" {
name = "gcp_gw_conn"
location = "${azurerm_resource_group.resource_group_1.location}"
resource_group_name = "${azurerm_resource_group.resource_group_1.name}"
type = "IPsec"
virtual_network_gateway_id = "${azurerm_virtual_network_gateway.az_vnet_gw.id}"
local_network_gateway_id = "${azurerm_local_network_gateway.gcp_local_vnet_gw.id}"
shared_key = "123456789"
}
A repository containing all the code to run a terraform deploy
will be added soon.