
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Multicloud architectures are standard in 2026, but network integration remains the primary failure point for teams attempting hybrid deployments. When you connect AWS and Azure with a Site-to-Site VPN, you create an encrypted IPsec tunnel that allows private RFC1918 traffic to flow securely between cloud providers without traversing the public internet unencrypted. This guide provides the exact Terraform configurations, routing logic, and high-availability patterns I use in production environments, moving beyond basic tutorials to address real-world latency, MTU, and compliance requirements.
How do you plan IP addressing when connecting AWS and Azure?
Before writing any Terraform or clicking through portals, you must validate your IP addressing strategy. The most common reason a new AWS VPC setup fails to peer with Azure is overlapping CIDR blocks. IPsec does not perform NAT by default; if both clouds use 10.0.0.0/16, routing will fail silently or asymmetrically.
Non-overlapping CIDR allocation
Assign distinct, non-overlapping ranges for each cloud environment. In my multicloud projects, I typically reserve larger supernets and carve out specific subnets for peering:
- AWS VPC: 10.10.0.0/16 (Subnets: 10.10.1.0/24, 10.10.2.0/24)
- Azure VNet: 10.20.0.0/16 (Subnets: 10.20.1.0/24, 10.20.2.0/24)
- Gateway Subnet (Azure): Must be named exactly
GatewaySubnetand sized at least /27 (I recommend /26 for future-proofing).
Transit considerations for Nepal and global teams
For teams operating out of Nepal or South Asia, remember that direct cloud-to-cloud traffic often routes through Singapore or Mumbai exchange points. While this doesn't change IP planning, it impacts latency expectations. If you anticipate adding an on-premises data center in Kathmandu later, reserve a third CIDR block (e.g., 192.168.0.0/16) now to avoid re-addressing during future hybrid expansions. Document these allocations in your infrastructure repository alongside your Terraform state management configuration to prevent accidental reuse.
What are the exact IPsec parameters for AWS-Azure interoperability?
AWS and Azure support multiple encryption standards, but they do not share identical defaults. A mismatch in Phase 1 (IKE) or Phase 2 (IPsec) proposals causes immediate tunnel failure. For production workloads in 2026, use IKEv2 with AES-256-GCM for both performance and security compliance.
Matching cryptographic proposals
Configure these exact parameters on both sides. AWS uses "Customer Gateway" + "VPN Connection" terminology, while Azure uses "Local Network Gateway" + "Virtual Network Gateway Connection".
| Parameter | Recommended Value | AWS Terminology | Azure Terminology |
|---|---|---|---|
| IKE Version | IKEv2 | IKEv2 | IKEv2 |
| Phase 1 Encryption | AES256-GCM-16 | AES256-GCM-16 | AES256GCM |
| Phase 1 Integrity | SHA2-384 | SHA2-384 | SHA384 |
| Phase 1 DH Group | Group 16 (MODP-4096) | modp4096 | DHGroup16 |
| Phase 2 Encryption | AES256-GCM-16 | AES256-GCM-16 | AES256GCM |
| Phase 2 Integrity | SHA2-384 | SHA2-384 | SHA384 |
| PFS Group | Group 16 (MODP-4096) | modp4096 | PFS2048 (or match DH16) |
| Lifetime (Phase 1) | 28,800 seconds (8h) | 28800 | 28800 |
| Lifetime (Phase 2) | 3,600 seconds (1h) | 3600 | 3600 |
Critical note on DPDP: Enable Dead Peer Detection on both ends. AWS enables it by default; on Azure, ensure your connection resource specifies dpd_detection_mode = "OnDemand" or "AlwaysOn". Without DPD, a silent peer failure can leave blackhole routes for up to 10 minutes before TCP timeouts trigger recovery.
How do you implement high availability for cross-cloud VPNs?
Never run a single tunnel in production. Both AWS and Azure charge per tunnel hour regardless of utilization, so running two tunnels costs marginally more but eliminates single points of failure. The architectural pattern differs depending on whether you use BGP or static routing.
BGP vs. Static Routing decision matrix
Choose BGP for any environment requiring automatic failover or dynamic route propagation. Static routing is acceptable only for dev/test or single-purpose batch pipelines where manual intervention during outage is tolerable.
- Create two Customer Gateways in AWS — one for each Azure gateway public IP.
- Create two VPN Connections attached to the same Virtual Private Gateway, each pointing to a different Customer Gateway.
- Configure Azure Local Network Gateways — create two LNG resources, each containing one AWS tunnel endpoint IP.
- Establish two Connections in Azure linking the single VNet Gateway to both Local Network Gateways.
- Enable BGP on all four endpoints using unique ASN pairs (e.g., AWS 65010, Azure 65020). Use AS-path prepending on the secondary tunnel to influence preference rather than relying solely on weight/local-pref.
With BGP enabled, convergence after tunnel failure typically occurs within 30–60 seconds. Without BGP, failover depends entirely on health check intervals and route table updates, which can exceed 5 minutes. For SOC 2 or ISO 27001 audited environments, BGP-driven automated failover is effectively mandatory to demonstrate RTO compliance.
How do you automate the VPN deployment with Terraform?
Manual portal configuration is unacceptable for production multicloud networking. Infrastructure as Code ensures reproducibility, version control, and audit trails. Below is a condensed Terraform pattern focusing on the critical interconnection resources. Store sensitive pre-shared keys in AWS Secrets Manager and Azure Key Vault, referencing them via data sources rather than hardcoding. Refer to my guide on handling secrets in CI/CD pipelines safely for secure injection patterns.
# AWS Side - Customer Gateway & VPN Connection
resource "aws_customer_gateway" "azure_cgw_1" {
bgp_asn = 65020
ip_address = var.azure_vng_public_ip_1
type = "ipsec.1"
tags = { Name = "azure-cgw-primary" }
}
resource "aws_vpn_connection" "to_azure_primary" {
customer_gateway_id = aws_customer_gateway.azure_cgw_1.id
vpn_gateway_id = aws_vpn_gateway.main.id
type = "ipsec.1"
static_routes_only = false
# Explicitly set Phase 1 & 2 to match Azure
phase1_encryption_algorithms = ["AES256-GCM-16"]
phase1_integrity_algorithms = ["SHA2-384"]
phase1_dh_group_numbers = [16]
phase2_encryption_algorithms = ["AES256-GCM-16"]
phase2_integrity_algorithms = ["SHA2-384"]
phase2_dh_group_numbers = [16]
tunnel1_preshared_key = data.aws_secretsmanager_secret_version.vpn_psk_1.secret_string
tunnel2_preshared_key = data.aws_secretsmanager_secret_version.vpn_psk_2.secret_string
}
# Azure Side - Local Network Gateway & Connection
resource "azurerm_local_network_gateway" "aws_lng_1" {
name = "aws-lng-primary"
location = var.azure_region
resource_group_name = var.azure_rg_name
gateway_address = aws_vpn_connection.to_azure_primary.tunnel1_address
bgp_settings {
asn = 65010
bgp_peering_address = aws_vpn_connection.to_azure_primary.tunnel1_bgp_inside_ip_addresses[0]
}
}
resource "azurerm_virtual_network_gateway_connection" "to_aws_primary" {
name = "aws-conn-primary"
location = var.azure_region
resource_group_name = var.azure_rg_name
type = "IPsec"
virtual_network_gateway_id = azurerm_virtual_network_gateway.main.id
local_network_gateway_id = azurerm_local_network_gateway.aws_lng_1.id
shared_key = data.azurerm_key_vault_secret.vpn_psk_1.value
enable_bgp = true
routing_weight = 10
ipsec_policy {
ike_encryption = "AES256"
ike_integrity = "SHA384"
ipsec_encryption = "AES256GCM"
ipsec_integrity = "SHA384"
dh_group = "DHGroup16"
pfs_group = "PFS2048"
sa_lifetime = 3600
}
} This snippet omits the gateway creation itself (which takes 30–45 minutes on Azure) to focus on the interconnection logic. Always define ipsec_policy explicitly in Azure; omitting it falls back to defaults that rarely match AWS custom configurations. Run terraform plan against a staging environment first to validate parameter compatibility before applying to production.
What monitoring and MTU adjustments prevent silent failures?
Tunnel establishment does not guarantee functional throughput. Two operational issues consistently degrade cross-cloud performance: MTU mismatches and insufficient observability.
MTU clamping for IPsec overhead
Standard Ethernet MTU is 1500 bytes. IPsec encapsulation adds 50–80 bytes of header overhead depending on encryption mode. Without adjustment, packets exceeding ~1420 bytes fragment or drop silently, causing application-layer timeouts despite healthy tunnel status. Configure MSS clamping on both sides:
- AWS: Set
tunnel_inside_cidrappropriately and enable jumbo frame support on the VGW if using DX later. For pure VPN, rely on instance-level TCP MSS clamping via iptables/nftables or cloud-init scripts. - Azure: The VNet Gateway handles fragmentation automatically for most cases, but verify effective MTU with
ping -M do -s 1400 <remote-private-ip>from VMs on both sides. Increase test size incrementally to find the true path MTU.
Observability stack for tunnel health
Monitor tunnel state AND throughput independently. Tunnel status UP does not mean traffic is flowing. Implement the following checks aligned with the four golden signals of monitoring:
- AWS CloudWatch:
TunnelState(binary),TunnelDataIn/TunnelDataOut(bytes/sec). Alert on TunnelState=0 OR DataOut=0 for >5min when expected traffic exists. - Azure Monitor:
TunnelAverageBandwidth,TunnelEgressBytes/TunnelIngressBytes. Create composite alerts combining connectivity + throughput metrics. - Synthetic probes: Deploy lightweight ping/HTTP health checks between EC2 and Azure VM instances every 60 seconds. Log results to your centralized platform (Prometheus/Grafana or equivalent) to correlate tunnel events with application impact.
Operational checklist for production readiness
Before declaring your cross-cloud VPN production-ready, verify these items. Skipping any single one has caused outages in environments I've audited:
- Confirm non-overlapping CIDRs documented in IaC repository
- Validate matching IPsec/IKE parameters via
terraform planoutput review - Test failover by administratively disabling primary tunnel and measuring convergence time
- Verify MTU with incremental ping tests across the tunnel
- Confirm BGP session establishment and route advertisement on both peers
- Set up alerts for BOTH tunnel state AND throughput anomalies
- Document PSK rotation procedure and schedule (quarterly minimum for compliance)
- Run load test simulating peak expected traffic to validate bandwidth tier sufficiency
Next steps for your multicloud network
When you connect AWS and Azure with a Site-to-Site VPN correctly, you gain a resilient foundation for multicloud applications, disaster recovery, and gradual migration strategies. Start with the Terraform patterns above, enforce strict parameter matching, and instrument thoroughly before carrying production traffic. If your team needs assistance designing compliant multicloud networking or validating existing VPN configurations against SOC 2 or ISO 27001 controls, reach out through my contact page to discuss your specific architecture. Proper groundwork now prevents costly rework and outages later.