Skip to main content

Multi-Cloud Networking


1 - Network architectures

1.1 Connectivity options

OptionLatencyBandwidthCost
InternetVariableVariableLow
VPNMediumUp to 1.25 GbpsMedium
DedicatedLow1-100 GbpsHigh

1.2 IP address planning

# Multi-Cloud IP Planning
aws:
region: eu-west-1
vpc_cidr: "10.0.0.0/16"
subnets:
private:
- "10.0.0.0/20"
- "10.0.16.0/20"
- "10.0.32.0/20"
public:
- "10.0.48.0/24"
- "10.0.49.0/24"

azure:
region: westeurope
vnet_cidr: "10.1.0.0/16"
subnets:
private:
- "10.1.0.0/20"
- "10.1.16.0/20"
gateway:
- "10.1.255.0/24"

gcp:
region: europe-west1
vpc_cidr: "10.2.0.0/16"
subnets:
private:
- "10.2.0.0/20"

2 - Site-to-Site VPN

2.1 AWS VPN to Azure

# AWS - Customer Gateway
resource "aws_customer_gateway" "azure" {
bgp_asn = 65001
ip_address = azurerm_public_ip.vpn.ip_address
type = "ipsec.1"

tags = {
Name = "azure-cgw"
}
}

# AWS - VPN Gateway
resource "aws_vpn_gateway" "main" {
vpc_id = aws_vpc.main.id

tags = {
Name = "main-vpn-gw"
}
}

# AWS - VPN Connection
resource "aws_vpn_connection" "azure" {
customer_gateway_id = aws_customer_gateway.azure.id
vpn_gateway_id = aws_vpn_gateway.main.id
type = "ipsec.1"

static_routes_only = false

tags = {
Name = "aws-to-azure"
}
}
# Azure - VPN Gateway
resource "azurerm_virtual_network_gateway" "main" {
name = "vpn-gateway"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name

type = "Vpn"
vpn_type = "RouteBased"
sku = "VpnGw1"

ip_configuration {
public_ip_address_id = azurerm_public_ip.vpn.id
private_ip_address_allocation = "Dynamic"
subnet_id = azurerm_subnet.gateway.id
}
}

# Azure - Local Gateway (AWS)
resource "azurerm_local_network_gateway" "aws" {
name = "aws-local-gw"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name

gateway_address = aws_vpn_connection.azure.tunnel1_address
address_space = ["10.0.0.0/16"]
}

# Azure - Connection
resource "azurerm_virtual_network_gateway_connection" "aws" {
name = "aws-connection"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name

type = "IPsec"
virtual_network_gateway_id = azurerm_virtual_network_gateway.main.id
local_network_gateway_id = azurerm_local_network_gateway.aws.id

shared_key = aws_vpn_connection.azure.tunnel1_preshared_key
}

2.2 AWS VPN to GCP

# GCP - VPN Gateway
resource "google_compute_vpn_gateway" "main" {
name = "vpn-gateway"
network = google_compute_network.main.id
region = var.gcp_region
}

# GCP - External VPN Gateway (AWS)
resource "google_compute_external_vpn_gateway" "aws" {
name = "aws-external-gateway"
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"

interface {
id = 0
ip_address = aws_vpn_connection.gcp.tunnel1_address
}
}

# GCP - VPN Tunnel
resource "google_compute_vpn_tunnel" "aws" {
name = "vpn-tunnel-aws"
region = var.gcp_region
vpn_gateway = google_compute_vpn_gateway.main.id
peer_external_gateway = google_compute_external_vpn_gateway.aws.id

shared_secret = aws_vpn_connection.gcp.tunnel1_preshared_key
peer_external_gateway_interface = 0
vpn_gateway_interface = 0

router = google_compute_router.main.id
}

3 - Dedicated interconnections

3.1 Options per cloud

CloudServiceBandwidth
AWSDirect Connect1-100 Gbps
AzureExpressRoute50 Mbps - 100 Gbps
GCPCloud Interconnect10-200 Gbps

3.2 AWS Direct Connect

resource "aws_dx_gateway" "main" {
name = "multicloud-dxgw"
amazon_side_asn = 64512
}

resource "aws_dx_gateway_association" "main" {
dx_gateway_id = aws_dx_gateway.main.id
associated_gateway_id = aws_vpn_gateway.main.id

allowed_prefixes = ["10.0.0.0/16"]
}

3.3 Megaport / Equinix Fabric

Use a third-party Cloud Router to connect multiple clouds:


4 - Multi-Cloud DNS

4.1 DNS architecture

4.2 Route 53 with Health Checks

# AWS Health Check
resource "aws_route53_health_check" "aws" {
fqdn = "app.aws.example.com"
port = 443
type = "HTTPS"
resource_path = "/health"
failure_threshold = "3"
request_interval = "30"
}

# Azure Health Check
resource "aws_route53_health_check" "azure" {
fqdn = "app.azure.example.com"
port = 443
type = "HTTPS"
resource_path = "/health"
failure_threshold = "3"
request_interval = "30"
}

# Failover Policy
resource "aws_route53_record" "primary" {
zone_id = aws_route53_zone.main.zone_id
name = "app.example.com"
type = "A"

failover_routing_policy {
type = "PRIMARY"
}

set_identifier = "primary"
health_check_id = aws_route53_health_check.aws.id

alias {
name = aws_lb.main.dns_name
zone_id = aws_lb.main.zone_id
evaluate_target_health = true
}
}

resource "aws_route53_record" "secondary" {
zone_id = aws_route53_zone.main.zone_id
name = "app.example.com"
type = "A"

failover_routing_policy {
type = "SECONDARY"
}

set_identifier = "secondary"
health_check_id = aws_route53_health_check.azure.id

alias {
name = "app.azure.example.com"
zone_id = "AZURE_ZONE_ID"
evaluate_target_health = true
}
}

4.3 Geo-Routing

# Europe -> Azure
resource "aws_route53_record" "europe" {
zone_id = aws_route53_zone.main.zone_id
name = "app.example.com"
type = "A"

geolocation_routing_policy {
continent = "EU"
}

set_identifier = "europe"

alias {
name = "app.azure.example.com"
zone_id = "AZURE_ZONE_ID"
}
}

# Americas -> AWS
resource "aws_route53_record" "americas" {
zone_id = aws_route53_zone.main.zone_id
name = "app.example.com"
type = "A"

geolocation_routing_policy {
continent = "NA"
}

set_identifier = "americas"

alias {
name = aws_lb.main.dns_name
zone_id = aws_lb.main.zone_id
}
}

5 - Global Load Balancing

5.1 Options

SolutionTypeMulti-Cloud
CloudFlareSaaSYes
AWS Global AcceleratorAWSNot native
Azure Front DoorAzureNot native
GCP Global Load BalancerGCPNot native

5.2 CloudFlare as GLB

# CloudFlare Load Balancer
resource "cloudflare_load_balancer" "main" {
zone_id = var.cloudflare_zone_id
name = "app.example.com"
fallback_pool_id = cloudflare_load_balancer_pool.azure.id
default_pool_ids = [
cloudflare_load_balancer_pool.aws.id,
cloudflare_load_balancer_pool.azure.id
]

steering_policy = "geo"

region_pools {
region = "WNAM"
pool_ids = [cloudflare_load_balancer_pool.aws.id]
}

region_pools {
region = "WEU"
pool_ids = [cloudflare_load_balancer_pool.azure.id]
}
}

resource "cloudflare_load_balancer_pool" "aws" {
name = "aws-pool"

origins {
name = "aws-origin"
address = "aws-app.example.com"
enabled = true
}

monitor = cloudflare_load_balancer_monitor.main.id
}

resource "cloudflare_load_balancer_pool" "azure" {
name = "azure-pool"

origins {
name = "azure-origin"
address = "azure-app.example.com"
enabled = true
}

monitor = cloudflare_load_balancer_monitor.main.id
}

Summary

In this chapter, we learned:

  • Multi-Cloud network architectures
  • Site-to-Site VPN between clouds
  • Dedicated interconnections
  • Multi-Cloud DNS and failover
  • Global Load Balancing

Next step

In the next chapter, we will look at Identity & Access Management.

→ Next chapter: Identity & Access


← Back to table of contents