Example: Geo-redundancy and fault isolation with VPNaaS

One of the key aspects to fully implement High-Availability (HA) is redundancy.  

❝ In engineering, redundancy is the duplication of critical components or functions of a system with the intention of increasing reliability of the system, usually in the form of a backup or fail-safe, or to improve actual system performance, [...] - Wikipedia

Geo-redundancy stresses this concept to a critical level where power-line issues or catastrophic events can massively impact a datacenter operability.

Openstack VPNaaS enables geo-redundancy and fault isolation, removing single-points of failure and ensuring high level of productivity of your application. 

This article describes how to setup a VPN connection between multiple CityCloud data-centers. Also, we will use Terraform to support and quickly configure our networks and routers.

Level

ADVANCED

Pre-requisites

  • A project enabled in each datacenter, similar to the above architecture
  • CLI access to each project
  • ICMP (ping) enabled via Security Groups
  • SSH access to the VMs in each project enabled via Security Groups
  • Terraform installed and good knowledge of the tool

    If you are new to Terraform and need a structured way of learning the tool and how it can benefit your CI/CD deployments, have a look at our City Cloud Academy courses.

Overview

In this article, we will describe how to connect Stockholm (Sto2),  Dubai (Dx1) and Frankfurt (Fra1) through VPNaaS connections as described below:



Only one VPN service per router is allowed as only one listener is used for VPN services.


Step-by-step guide


Stockholm - Sto2

1. Navigate to the directory containing your Terraform configuration

2. Source your openstack.rc file and run:

$ terraform init

3. Apply the VPNaaS configuration below:

// VPNaaS Configuration

resource
"openstack_vpnaas_service_v2" "geo-redundancy" {
name = "${var.prefix}-geo-redundancy"
router_id = openstack_networking_router_v2.router.id
admin_state_up = "true"
}

resource "openstack_vpnaas_ipsec_policy_v2" "geo-redundancy" {
name = "${var.prefix}-geo-redundancy"
pfs = "group5"
auth_algorithm = "sha1"
encryption_algorithm = "aes-128"
transform_protocol = "esp"
encapsulation_mode = "tunnel"
}

resource "openstack_vpnaas_ike_policy_v2" "geo-redundancy" {
name = "${var.prefix}-geo-redundancy"
pfs = "group5"
auth_algorithm = "sha1"
encryption_algorithm = "aes-128"
}

resource "openstack_vpnaas_endpoint_group_v2" "local" {
name = "${var.prefix}-local"
type = "subnet"
endpoints = [openstack_networking_subnet_v2.subnet.id]
}

resource "openstack_vpnaas_endpoint_group_v2" "peer" {
name = "${var.prefix}-peer"
type = "cidr"
endpoints = ["10.3.0.0/24"] // <-- Peer CIDR
}

resource "openstack_vpnaas_site_connection_v2" "subgw" {
name = "${var.prefix}-subgw"
ipsecpolicy_id = openstack_vpnaas_ipsec_policy_v2.geo-redundancy.id
ikepolicy_id = openstack_vpnaas_ike_policy_v2.geo-redundancy.id
local_ep_group_id = openstack_vpnaas_endpoint_group_v2.local.id
peer_ep_group_id = openstack_vpnaas_endpoint_group_v2.peer.id
vpnservice_id = openstack_vpnaas_service_v2.geo-redundancy.id
psk = "zvuGp9vuwLMpBoa..."
peer_address = "103.81.142.192" // <-- Peer Router Floating IP
peer_id = "103.81.142.192" // <-- Peer Router Floating IP
admin_state_up = "true"
}


4. Check the VPN service is enabled and in ACTIVE status.

In case the service is listed as DOWN right after it's been deployed, simply restart it via Openstack CLI:

$ openstack vpn service set <vpn-service> --disable
$ openstack vpn service set <vpn-service> --enable

Frankfurt - Fra1

1. Navigate to the directory containing your Terraform configuration

2. Source your openstack.rc file and run:

$ terraform init

3. Apply the VPNaaS configuration below:

// VPNaaS Configuration

resource
"openstack_vpnaas_service_v2" "geo-redundancy" {
name = "${var.prefix}-geo-redundancy"
router_id = openstack_networking_router_v2.router.id
admin_state_up = "true"
}

resource "openstack_vpnaas_ipsec_policy_v2" "geo-redundancy" {
name = "${var.prefix}-geo-redundancy"
pfs = "group5"
auth_algorithm = "sha1"
encryption_algorithm = "aes-128"
transform_protocol = "esp"
encapsulation_mode = "tunnel"
}

resource "openstack_vpnaas_ike_policy_v2" "geo-redundancy" {
name = "${var.prefix}-geo-redundancy"
pfs = "group5"
auth_algorithm = "sha1"
encryption_algorithm = "aes-128"
}

resource "openstack_vpnaas_endpoint_group_v2" "local" {
name = "${var.prefix}-local"
type = "subnet"
endpoints = [openstack_networking_subnet_v2.subnet.id]
}

resource "openstack_vpnaas_endpoint_group_v2" "peer" {
name = "${var.prefix}-peer"
type = "cidr"
endpoints = ["10.3.0.0/24"] // <-- Peer CIDR
}

resource "openstack_vpnaas_site_connection_v2" "subgw" {
name = "${var.prefix}-subgw"
ipsecpolicy_id = openstack_vpnaas_ipsec_policy_v2.geo-redundancy.id
ikepolicy_id = openstack_vpnaas_ike_policy_v2.geo-redundancy.id
local_ep_group_id = openstack_vpnaas_endpoint_group_v2.local.id
peer_ep_group_id = openstack_vpnaas_endpoint_group_v2.peer.id
vpnservice_id = openstack_vpnaas_service_v2.geo-redundancy.id
psk = "zvuGp9vuwLMpBoaWPUTq63LFcmK7GnAH"
peer_address = "103.81.142.192" // <-- Peer Router Floating IP
peer_id = "103.81.142.192" // <-- Peer Router Floating IP
admin_state_up = "true"
}

4. Check the VPN service is enabled and in ACTIVE status.

In case the service is listed as DOWN right after it's been deployed, simply restart it via Openstack CLI:

$ openstack vpn service set <vpn-service> --disable
$ openstack vpn service set <vpn-service> --enable

Dubai - Dx1

1. Navigate to the directory containing your Terraform configuration

2. Source your openstack.rc file and run:

$ terraform init

3. Apply the VPNaaS configuration below:

// VPNaaS Configuration

resource
"openstack_vpnaas_endpoint_group_v2" "local" {
name = "${var.prefix}-local"
type = "subnet"
endpoints = [openstack_networking_subnet_v2.subnet.id]
}

resource "openstack_vpnaas_service_v2" "geo-redundancy" {
name = "${var.prefix}-geo-redundancy"
router_id = openstack_networking_router_v2.router.id
admin_state_up = "true"
}

// Create VPN Network - Sto2

resource "openstack_vpnaas_ipsec_policy_v2" "sto2" {
name = "${var.prefix}-geo-redundancy"
pfs = "group5"
auth_algorithm = "sha1"
encryption_algorithm = "aes-128"
transform_protocol = "esp"
encapsulation_mode = "tunnel"
}

resource "openstack_vpnaas_ike_policy_v2" "sto2" {
name = "${var.prefix}-geo-redundancy"
pfs = "group5"
auth_algorithm = "sha1"
encryption_algorithm = "aes-128"
}

resource "openstack_vpnaas_endpoint_group_v2" "sto2" {
name = "${var.prefix}-peer"
type = "cidr"
endpoints = ["10.1.0.0/24"] // <-- Peer CIDR
}

resource "openstack_vpnaas_site_connection_v2" "sto2" {
name = "${var.prefix}-geo-redundancy"
ipsecpolicy_id = openstack_vpnaas_ipsec_policy_v2.sto2.id
ikepolicy_id = openstack_vpnaas_ike_policy_v2.sto2.id
local_ep_group_id = openstack_vpnaas_endpoint_group_v2.local.id
peer_ep_group_id = openstack_vpnaas_endpoint_group_v2.sto2.id
vpnservice_id = openstack_vpnaas_service_v2.geo-redundancy.id
psk = "zvuGp9vuwLMpBoa..."
peer_address = "31.12.86.44" // <-- Peer Router Floating IP
peer_id = "31.12.86.44" // <-- Peer Router Floating IP
admin_state_up = "true"
}

// Create VPN Network - Fra1

resource "openstack_vpnaas_ipsec_policy_v2" "fra1" {
name = "${var.prefix}-geo-redundancy"
pfs = "group5"
auth_algorithm = "sha1"
encryption_algorithm = "aes-128"
transform_protocol = "esp"
encapsulation_mode = "tunnel"
}

resource "openstack_vpnaas_ike_policy_v2" "fra1" {
name = "${var.prefix}-geo-redundancy"
pfs = "group5"
auth_algorithm = "sha1"
encryption_algorithm = "aes-128"
}

resource "openstack_vpnaas_endpoint_group_v2" "fra1" {
name = "${var.prefix}-peer"
type = "cidr"
endpoints = ["10.2.0.0/24"] // <-- Peer CIDR
}

resource "openstack_vpnaas_site_connection_v2" "fra1" {
name = "${var.prefix}-geo-redundancy"
ipsecpolicy_id = openstack_vpnaas_ipsec_policy_v2.fra1.id
ikepolicy_id = openstack_vpnaas_ike_policy_v2.fra1.id
local_ep_group_id = openstack_vpnaas_endpoint_group_v2.local.id
peer_ep_group_id = openstack_vpnaas_endpoint_group_v2.fra1.id
vpnservice_id = openstack_vpnaas_service_v2.geo-redundancy.id
psk = "zvuGp9vuwLMpBoa..."
peer_address = "45.114.123.30" // <-- Peer Router Floating IP
peer_id = "45.114.123.30" // <-- Peer Router Floating IP
admin_state_up = "true"
}

4. Check the VPN service is enabled and in ACTIVE status.

In case the service is listed as DOWN right after it's been deployed, simply restart it via Openstack CLI:

$ openstack vpn service set <vpn-service> --disable
$ openstack vpn service set <vpn-service> --enable

Tests and verification

1. SSH into one of the VMs in Dubai-Dx1Test infra-projects connectivity

2. Ping one of the VMs in Stockholm-Sto2 using the local ip 10.1.0.x and check traffic flows:

$ ping 10.1.0.175
PING 10.1.0.175 (10.1.0.175) 56(84) bytes of data.
64 bytes from 10.1.0.175: icmp_seq=1 ttl=62 time=147 ms
64 bytes from 10.1.0.175: icmp_seq=2 ttl=62 time=147 ms
64 bytes from 10.1.0.175: icmp_seq=3 ttl=62 time=147 ms

3. Ping one of the VMs in Frankfurst-Fra1 using the local ip 10.2.0.y and check traffic flows:

$ ping 10.2.0.155
PING 10.2.0.155 (10.2.0.155) 56(84) bytes of data.
64 bytes from 10.2.0.155: icmp_seq=1 ttl=62 time=117 ms
64 bytes from 10.2.0.155: icmp_seq=2 ttl=62 time=117 ms
64 bytes from 10.2.0.155: icmp_seq=3 ttl=62 time=117 ms

Conclusions

This article presented how our City Cloud infrastructure copes with such important requirements as redundancy and fault isolation. Additional work may be required at platform and application level to fully enable High-Availability (HA).