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
| Parameter | Value | Description |
|---|---|---|
| IKE encryption | aes256 | Encryption algorithm for IKE negotiation |
| IKE hash | sha256 | Hash algorithm for IKE integrity |
| IKE DH group | 14 | Diffie-Hellman group (2048-bit MODP) |
| IKE lifetime | 28800 | IKE SA lifetime in seconds (8 hours) |
| ESP encryption | aes256 | Encryption algorithm for data traffic |
| ESP hash | sha256 | Hash algorithm for ESP integrity |
| ESP lifetime | 3600 | ESP SA lifetime in seconds (1 hour) |
| DPD interval | 30 | Dead peer detection interval in seconds |
| DPD timeout | 120 | Dead 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
| Consideration | WireGuard | IPSec |
|---|---|---|
| Configuration | Simple -- fewer parameters | Complex -- many negotiation options |
| Performance | Higher throughput, lower overhead | Good but higher encryption overhead |
| Compatibility | Requires WireGuard on both sides | Works with nearly all VPN gateways |
| Compliance | No formal RFC | IETF 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
Related Documentation
- Cloud Router reference -- all cloud router Terraform resources and examples
- Connecting Multiple Sites with Magic Mesh -- automatic full-mesh connectivity between cloud routers
Need Help?
Contact support@netactuate.com or open a support ticket from the portal.