OCI Site-to-Site VPN provides encrypted IPSec connectivity between your on-premises network and OCI VCNs over the public internet. Each VPN connection consists of two tunnels for redundancy, and supports both static routing and BGP dynamic routing. BGP is the recommended approach for production environments because it provides automatic failover between tunnels and supports route propagation from on-premises to OCI without manual route table maintenance. This post covers the full setup with Terraform.
Step 1: Customer Premises Equipment and IPSec Connection
resource "oci_core_drg" "production_drg" {
compartment_id = var.compartment_id
display_name = "production-drg"
}
resource "oci_core_drg_attachment" "vcn_to_drg" {
drg_id = oci_core_drg.production_drg.id
vcn_id = var.vcn_id
display_name = "production-vcn-to-drg"
}
resource "oci_core_cpe" "on_premises_router" {
compartment_id = var.compartment_id
display_name = "on-premises-firewall"
ip_address = var.on_premises_public_ip
# Use a CPE device shape that matches your hardware for configuration templates
cpe_device_shape_id = "CISCO_ASA"
}
resource "oci_core_ipsec" "site_to_site_vpn" {
compartment_id = var.compartment_id
display_name = "production-site-to-site-vpn"
cpe_id = oci_core_cpe.on_premises_router.id
drg_id = oci_core_drg.production_drg.id
# BGP dynamic routing - recommended over static routes
static_routes = []
cpe_local_identifier = var.on_premises_public_ip
cpe_local_identifier_type = "IP_ADDRESS"
defined_tags = { "Operations.ManagedBy" = "terraform", "Operations.Environment" = "production" }
}
output "ipsec_connection_id" { value = oci_core_ipsec.site_to_site_vpn.id }
Step 2: Tunnel Configuration with BGP
resource "oci_core_ipsec_connection_tunnel_management" "tunnel_1" {
ipsec_id = oci_core_ipsec.site_to_site_vpn.id
tunnel_id = data.oci_core_ipsec_connection_tunnels.tunnels.ip_sec_connection_tunnels[0].id
display_name = "vpn-tunnel-1-bgp"
routing = "BGP"
bgp_session_info {
customer_bgp_asn = var.on_premises_bgp_asn
customer_interface_ip = "10.10.10.1/30"
oracle_interface_ip = "10.10.10.2/30"
}
phase_one_details {
is_custom_phase_one_config = true
authentication_algorithm = "SHA2_384"
encryption_algorithm = "AES_256_CBC"
diffie_hellman_group = "GROUP20"
lifetime_in_seconds = 28800
}
phase_two_details {
is_custom_phase_two_config = true
authentication_algorithm = "HMAC_SHA2_256_128"
encryption_algorithm = "AES_256_GCM"
lifetime_in_seconds = 3600
is_pfs_enabled = true
pfs_dh_group = "GROUP20"
}
shared_secret = var.vpn_tunnel_1_psk
ike_version = "V2"
}
resource "oci_core_ipsec_connection_tunnel_management" "tunnel_2" {
ipsec_id = oci_core_ipsec.site_to_site_vpn.id
tunnel_id = data.oci_core_ipsec_connection_tunnels.tunnels.ip_sec_connection_tunnels[1].id
display_name = "vpn-tunnel-2-bgp-backup"
routing = "BGP"
bgp_session_info {
customer_bgp_asn = var.on_premises_bgp_asn
customer_interface_ip = "10.10.20.1/30"
oracle_interface_ip = "10.10.20.2/30"
}
phase_one_details {
is_custom_phase_one_config = true
authentication_algorithm = "SHA2_384"
encryption_algorithm = "AES_256_CBC"
diffie_hellman_group = "GROUP20"
lifetime_in_seconds = 28800
}
phase_two_details {
is_custom_phase_two_config = true
authentication_algorithm = "HMAC_SHA2_256_128"
encryption_algorithm = "AES_256_GCM"
lifetime_in_seconds = 3600
is_pfs_enabled = true
pfs_dh_group = "GROUP20"
}
shared_secret = var.vpn_tunnel_2_psk
ike_version = "V2"
}
Step 3: Tunnel Status Alarm
resource "oci_monitoring_alarm" "vpn_tunnel_down" {
compartment_id = var.compartment_id
display_name = "vpn-tunnel-status-down"
is_enabled = true
metric_compartment_id = var.compartment_id
namespace = "oci_vpn"
query = "TunnelState[5m]{ipsecId = 'IPSEC_OCID'}.mean() < 1"
severity = "CRITICAL"
pending_duration = "PT5M"
destinations = [var.ops_notification_topic_id]
body = "One or more VPN tunnels are down. Check on-premises CPE configuration and BGP session status. If both tunnels are down, on-premises connectivity to OCI is completely lost."
}
Operational Notes
OCI provisions two IPSec tunnel headends in different fault domains for every connection. Your on-premises CPE should maintain active BGP sessions to both tunnels. Configure your CPE to prefer one tunnel by adjusting BGP local preference or MED attributes, and use the other as a hot standby. If the primary tunnel goes down, BGP failover to the standby tunnel typically completes in under 30 seconds, depending on your BGP hold timer configuration.
Use IKEv2 with AES-256-GCM in Phase 2 for maximum security and performance. IKEv1 is supported but has a longer negotiation sequence and does not support AEAD ciphers. Generate separate pre-shared keys for each tunnel. A compromised PSK only affects one tunnel, and the key rotation process interrupts traffic only on the tunnel being rekeyed while the other tunnel continues passing traffic.
Regards,
Osama
#OCI #OracleCloud #SiteToSiteVPN #IPSec #BGP #Terraform #IaC #TechBlog #Oracle #PlatformEngineering #NetworkSecurity #HybridCloud #OracleCloudInfrastructure #DRG #VPN #IKEv2 #CPE #NetworkConnectivity #HighAvailability #CloudNetworking
Leave a Reply