Docs
Open the console →
Guides

Cross-cloud connections (site-to-site VPN)

Link two connected clouds with a first-class network connection — a site-to-site IPsec VPN across any of the six cloud pairs (AWS, GCP, Azure, Alibaba), provisioned through the Terraform engine and drawn as a cross-cloud edge on the topology map. The shared key is generated server-side and never shown.

A cross-cloud connection is a network link between two clouds you have already connected — for example an AWS VPC ⇄ Azure VNet site-to-site IPsec VPN. It is a first-class object (not a discovered link): it spans two accounts, carries its own provisioning state, tunnel state and an encrypted pre-shared key, and it survives every inventory sync of either side. Cloud Control provisions it through the same Terraform engine that backs every other mutation and draws it as a distinct edge between the two clouds' network nodes on the Network map.

All six cloud pairs are supported

Every unordered pair of the four clouds can be linked with a site-to-site VPN — the universal path, since every cloud has an IPsec VPN gateway. Each pair composes the correct native resources on both sides in one apply:

  • AWS ⇄ Azureaws_vpn_gateway/aws_customer_gateway/aws_vpn_connectionazurerm_virtual_network_gateway/azurerm_local_network_gateway/azurerm_virtual_network_gateway_connection.
  • AWS ⇄ GCP — AWS VPN gateway ⇄ google_compute_ha_vpn_gateway/google_compute_external_vpn_gateway/google_compute_vpn_tunnel + a BGP google_compute_router.
  • AWS ⇄ Alibaba — AWS VPN gateway ⇄ alicloud_vpn_gateway/alicloud_vpn_customer_gateway/alicloud_vpn_connection.
  • GCP ⇄ Azure — GCP HA VPN ⇄ Azure VNet gateway.
  • GCP ⇄ Alibaba — GCP HA VPN ⇄ Alibaba VPN gateway.
  • Azure ⇄ Alibaba — Azure VNet gateway ⇄ Alibaba VPN gateway.

Before you start

Connect two clouds on different providers and let them sync so each side has a discoverable network. You need the manage cloud accounts capability (Org Admin / SRE · Cloud Admin) to create or delete a connection — a read-only or Viewer role sees the list but can't mutate it.

  1. Open Connections

    The Connections screen (/connections) lists your cross-cloud links. With fewer than two clouds connected it shows an honest empty state ("connect at least two clouds to link them").

  2. Create the connection

    Pick account A and account B (different clouds), the type (site-to-site VPN), and each side's advertised CIDR, then Create. POST /api/cloud/connections validates both accounts are healthy and different providers, resolves each side's network, and generates the shared key.

  3. Provisioning

    The connection is created planned, then a Terraform workspace (xconn-<id>) composes the pair's two-provider module and the mock runner applies it — the connection moves through provisioning to up with a pair of tunnels.

  4. See it on the map

    The Network topology draws a distinct dashed cross-cloud edge between the two clouds' networks, with a hover detail showing the peer clouds, type, status and tunnel count.

Draw a connector on the map

You can also create a connection by drawing it on the Network topology. Turn on Connect mode (the toolbar toggle, shown to anyone with the *manage cloud accounts* capability), then drag an arrow from one VPC/VNet (or subnet) node to another. The arrow's direction is the intent: A → B means "A initiates reachability to B". Same provider auto-picks VPC peering; different providers auto-pick the site-to-site VPN. Release on a valid target to open a prefilled panel — endpoints, type, each side's CIDR, the allow rules (protocol + port range), the direction (A→B or bidirectional) and, for a VPN, the routing mode — then Create & provision. Press Esc to cancel a draw.

The direction drives two things at once. Routes are provisioned both ways — a link needs a return route, so a route to B's CIDR is added on A's side *and* a route to A's CIDR on B's side. The security permission is one-way per the arrow — A → B adds an *ingress-allow on B* for A's CIDR on the drawn protocol/ports (nothing is opened for B to initiate back). A bidirectional toggle mirrors the allow so both sides may initiate. Same-cloud peering and cross-cloud VPN both render as a directional connector edge with an arrowhead.

Route + security fidelity is AWS-first

This release emits the real route entries (aws_route, both sides) and the direction-aware security allow rules (aws_security_group_rule, ingress on the target / egress on the source) for AWS. GCP, Azure and Alibaba route + security rules are stubbed with a clearly-marked placeholder in the composed module and land in a follow-on phase; their peering/VPN gateways provision as before. The connector is applied by the mock runner now; the real terraform apply inherits the same module via the real-runner path.

How the two-provider module works

A single HCL-JSON module carries both provider sides so Terraform resolves each side's public IP in one apply: each cloud's VPN gateway plus a peer-facing gateway that references the other side's public/outside IP, and a connection bound to the shared key. The pre-shared key is a sensitive Terraform variable (var.shared_key) — its value is never written into the composed artifact, so the committed GitOps HCL references the variable only.

The shared key is never shown

The PSK is generated server-side (crypto-random), stored only as an AES-256-GCM envelope under CC_DATA_KEY, and injected into the apply as a sensitive variable. No API response ever returns it — the connection object exposes secretSet: true only. Rotating the key re-plans and re-applies the connection.

Removing a connection

Delete a connection is a soft-disconnect: the row is retained for history and drops off the list and the map. An account that is an endpoint of a live connection cannot be hard-deleted (purged) until you delete the connection first — Cloud Control refuses with a 409 rather than orphaning the peer's link.

Limitations

Apply is the mock runner this round

"Provisioned" means the two-provider HCL-JSON module is composed, planned, approved and the deterministic runner writes tunnel state + GitOps HCL — but no real terraform apply runs against your live clouds yet, so the actual IPsec tunnel is not established until the real-runner round (the sandboxed short-lived-creds runner is the next phase).

  • Native interconnect is modeled only. Each pair also models its cloud-native private interconnect (Direct Connect / ExpressRoute / Partner Interconnect / Express Connect), drawn and tracked, but these need a physical/partner circuit Cloud Control cannot auto-order — so only the site-to-site VPN type is auto-provisioned.
  • PSK rotation re-applies. There is no in-place tunnel-key hot-swap — rotating the shared key runs a fresh apply.
  • The map assumes both accounts are synced. A connection to an un-synced/disconnected endpoint shows as down rather than drawing a dangling edge.