Skip to main content

Site-to-Site VPN with Cloud Routers

NetActuate cloud routers support IPSec and WireGuard VPN tunnels for secure connectivity between your NetActuate infrastructure and on-premises networks or third-party cloud providers. This guide covers deploying a cloud router and configuring each tunnel type with Terraform.

What You Will Build

By the end of this guide you will have:

  • A cloud router deployed at a NetActuate location
  • An IPSec IKEv2 tunnel connecting the router to a remote site
  • A static route directing traffic for the remote network through the tunnel
  • Alternatively, a WireGuard tunnel for simpler, high-performance site-to-site connectivity

Prerequisites

  • A NetActuate account with API access
  • Terraform 1.0 or later installed locally
  • A NetActuate API key (generate one under Account -> API Keys in the portal)
  • The public IP address of your remote site's VPN endpoint
  • A pre-shared key (PSK) agreed upon with the remote site administrator

IPSec VPN

IPSec is the standard choice when connecting to enterprise firewalls, third-party cloud VPN gateways (AWS VGW, Azure VPN Gateway, GCP Cloud VPN), or legacy on-premises equipment.

Step 1: Deploy a Cloud Router

terraform {
required_providers {
netactuate = {
source = "netactuate/netactuate"
version = ">= 2.0.0"
}
}
}

provider "netactuate" {
api_key = var.netactuate_api_key
}

variable "netactuate_api_key" {
type = string
sensitive = true
}

variable "ipsec_psk" {
type = string
sensitive = true
}

resource "netactuate_router" "vpn_gw" {
name = "vpn-gateway-lax"
location = "LAX"
plan = "VR2x2x25"
}

Step 2: Configure Global IPSec Settings

The global IPSec resource sets IKE and ESP parameters that apply to all peers on the router.

resource "netactuate_router_ipsec" "global" {
router_id = netactuate_router.vpn_gw.id

ike_encryption = "aes256"
ike_hash = "sha256"
ike_dh_group = 14
ike_lifetime = 28800

esp_encryption = "aes256"
esp_hash = "sha256"
esp_lifetime = 3600

dpd_interval = 30
dpd_timeout = 120
}

Step 3: Create an IPSec Peer

Define the remote site as an IPSec peer. The overlay_ipv4 addresses create a point-to-point link inside the tunnel for routing.

resource "netactuate_router_vrf_ipsec_peer" "remote_site" {
router_id = netactuate_router.vpn_gw.id
vrf_id = netactuate_router.vpn_gw.default_vrf_id
description = "headquarters-dc"

remote_id = "203.0.113.1"
psk_secret = var.ipsec_psk
peer_address = "203.0.113.1"
overlay_ipv4 = "169.254.100.1/30"
do_initiate_connection = true

ike_version = 2
}

Setting do_initiate_connection to true tells the cloud router to actively initiate the IKE negotiation rather than waiting for the remote side.

Step 4: Add a Static Route

Route traffic for the remote site's network through the IPSec tunnel.

resource "netactuate_router_static_route" "remote_network" {
router_id = netactuate_router.vpn_gw.id
destination = "192.168.0.0/16"
next_hop = "169.254.100.2"
}

The next hop (169.254.100.2) is the remote side's overlay address inside the tunnel. Traffic matching 192.168.0.0/16 is encapsulated and sent through the IPSec tunnel to the remote endpoint.

IPSec Parameter Reference

ParameterValueDescription
IKE encryptionaes256Encryption algorithm for IKE negotiation
IKE hashsha256Hash algorithm for IKE integrity
IKE DH group14Diffie-Hellman group (2048-bit MODP)
IKE lifetime28800IKE SA lifetime in seconds (8 hours)
ESP encryptionaes256Encryption algorithm for data traffic
ESP hashsha256Hash algorithm for ESP integrity
ESP lifetime3600ESP SA lifetime in seconds (1 hour)
DPD interval30Dead peer detection interval in seconds
DPD timeout120Dead peer detection timeout in seconds

Note: Match these values exactly on the remote side. Mismatched parameters are the most common cause of IKE negotiation failures.


WireGuard VPN

WireGuard is a modern alternative to IPSec that offers simpler configuration and higher throughput. Use it when both endpoints support WireGuard and you do not need strict IPSec compliance.

Step 1: Create a WireGuard Interface

Attach a WireGuard interface to the router's VRF with a listen port and tunnel address.

resource "netactuate_router_vrf_interface" "wg0" {
router_id = netactuate_router.vpn_gw.id
vrf_id = netactuate_router.vpn_gw.default_vrf_id
name = "wg0"
type = "wireguard"
address = "10.100.0.1/24"

wireguard {
listen_port = 51820
}
}

Unlike IPSec, WireGuard does not require global settings. Each interface is self-contained.

Step 2: Add a WireGuard Peer

Define the remote endpoint as a peer on the WireGuard interface.

resource "netactuate_router_vrf_interface_wireguard_peer" "remote" {
router_id = netactuate_router.vpn_gw.id
vrf_id = netactuate_router.vpn_gw.default_vrf_id
interface_id = netactuate_router_vrf_interface.wg0.id
public_key = var.wg_peer_public_key
allowed_ips = ["10.100.0.2/32", "192.168.0.0/16"]
endpoint = "203.0.113.1:51820"
}

The allowed_ips field serves two purposes: it defines which source IPs are accepted from this peer, and it acts as a routing table for outbound traffic. Include the peer's tunnel address and any networks behind it.

Step 3: Retrieve the Router's Public Key

The cloud router generates its WireGuard key pair automatically when the interface is created. Retrieve the public key from Terraform output or from the portal under Networking -> Cloud Routers -> (your router) -> Interfaces.

Add an output to your Terraform configuration to surface it:

output "wg_public_key" {
value = netactuate_router_vrf_interface.wg0.wireguard_public_key
}

Configure your remote site's WireGuard peer with this public key and set the endpoint to the cloud router's public IP on port 51820.

When to Use WireGuard vs IPSec

ConsiderationWireGuardIPSec
ConfigurationSimple -- fewer parametersComplex -- many negotiation options
PerformanceHigher throughput, lower overheadGood but higher encryption overhead
CompatibilityRequires WireGuard on both sidesWorks with nearly all VPN gateways
ComplianceNo formal RFCIETF standard, required by many frameworks

Use WireGuard when connecting to modern infrastructure you control and performance is a priority. Use IPSec when connecting to enterprise equipment, third-party cloud providers, or compliance-driven environments.


GRE Tunnels

For scenarios where encryption is handled at the application layer or not required, GRE tunnels provide a lightweight alternative. GRE encapsulates traffic without encrypting it, making it useful for overlay networks where you manage encryption separately.

resource "netactuate_router_vrf_tunnel" "gre_site_b" {
router_id = netactuate_router.vpn_gw.id
vrf_id = netactuate_router.vpn_gw.default_vrf_id
name = "gre-to-site-b"
type = "gre"
local_ip = netactuate_router.vpn_gw.ip_address
remote_ip = "203.0.113.5"
tunnel_ip = "10.200.0.1/30"
ip_key = 1
mtu = 1476
}

Key GRE parameters:

  • ip_key -- an integer key that both sides must match. Allows multiple GRE tunnels between the same pair of endpoints.
  • mtu -- set to 1476 (or lower) to account for GRE encapsulation overhead. The default Ethernet MTU of 1500 minus 24 bytes of GRE header.
  • remote_ip -- the public IP of the far-end tunnel endpoint.

Add a static route to direct traffic through the GRE tunnel:

resource "netactuate_router_static_route" "gre_remote" {
router_id = netactuate_router.vpn_gw.id
destination = "172.16.0.0/12"
next_hop = "10.200.0.2"
}

Note: GRE tunnels are unencrypted. Use them only when encryption is unnecessary or handled by a higher-layer protocol (such as TLS or application-level encryption).


Serialization Delay

Cloud router configuration changes are serialized with a 60-second interval between operations. Terraform handles the wait automatically, but plan for longer apply times when creating multiple tunnels, peers, or routes in a single run. A configuration with a router, IPSec global settings, one peer, and two static routes will take roughly 4-5 minutes to apply.

Advanced Resources

For the full list of cloud router resources, IPSec options, and tunnel configurations, see the Terraform provider repository:

https://github.com/netactuate/netactuate-terraform-router

Need Help?

Contact support@netactuate.com or open a support ticket from the portal.