Configure GCP HA VPN Gateways

The gcp:compute/haVpnGateway:HaVpnGateway resource, part of the Pulumi GCP provider, provisions a Google-managed HA VPN gateway that terminates VPN tunnels with automatic failover across two interfaces. This guide focuses on three capabilities: basic gateway creation, dual-stack IPv4/IPv6 support, and Cloud Interconnect integration.

HA VPN gateways attach to VPC networks and may integrate with Cloud Interconnect attachments and Cloud Routers for encrypted hybrid connectivity. The examples are intentionally small. Combine them with VPN tunnels, external VPN gateway definitions, and BGP configuration for complete connectivity.

Create a gateway for VPN tunnel termination

Most HA VPN deployments start by creating a gateway that terminates VPN tunnels from on-premises or other cloud environments, providing two interfaces for automatic failover.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const network1 = new gcp.compute.Network("network1", {
    name: "network1",
    autoCreateSubnetworks: false,
});
const haGateway1 = new gcp.compute.HaVpnGateway("ha_gateway1", {
    region: "us-central1",
    name: "ha-vpn-1",
    network: network1.id,
});
import pulumi
import pulumi_gcp as gcp

network1 = gcp.compute.Network("network1",
    name="network1",
    auto_create_subnetworks=False)
ha_gateway1 = gcp.compute.HaVpnGateway("ha_gateway1",
    region="us-central1",
    name="ha-vpn-1",
    network=network1.id)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		network1, err := compute.NewNetwork(ctx, "network1", &compute.NetworkArgs{
			Name:                  pulumi.String("network1"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewHaVpnGateway(ctx, "ha_gateway1", &compute.HaVpnGatewayArgs{
			Region:  pulumi.String("us-central1"),
			Name:    pulumi.String("ha-vpn-1"),
			Network: network1.ID(),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var network1 = new Gcp.Compute.Network("network1", new()
    {
        Name = "network1",
        AutoCreateSubnetworks = false,
    });

    var haGateway1 = new Gcp.Compute.HaVpnGateway("ha_gateway1", new()
    {
        Region = "us-central1",
        Name = "ha-vpn-1",
        Network = network1.Id,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.HaVpnGateway;
import com.pulumi.gcp.compute.HaVpnGatewayArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var network1 = new Network("network1", NetworkArgs.builder()
            .name("network1")
            .autoCreateSubnetworks(false)
            .build());

        var haGateway1 = new HaVpnGateway("haGateway1", HaVpnGatewayArgs.builder()
            .region("us-central1")
            .name("ha-vpn-1")
            .network(network1.id())
            .build());

    }
}
resources:
  haGateway1:
    type: gcp:compute:HaVpnGateway
    name: ha_gateway1
    properties:
      region: us-central1
      name: ha-vpn-1
      network: ${network1.id}
  network1:
    type: gcp:compute:Network
    properties:
      name: network1
      autoCreateSubnetworks: false

The gateway provisions two interfaces in the specified region, each with its own public IP address. The network property attaches the gateway to your VPC. After creating the gateway, you configure VPN tunnels that reference these interfaces and connect to your peer VPN devices.

Enable dual-stack IPv4 and IPv6 support

Applications migrating to IPv6 or requiring dual-stack connectivity can configure the gateway to support both IP families.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const network1 = new gcp.compute.Network("network1", {
    name: "network1",
    autoCreateSubnetworks: false,
});
const haGateway1 = new gcp.compute.HaVpnGateway("ha_gateway1", {
    region: "us-central1",
    name: "ha-vpn-1",
    network: network1.id,
    stackType: "IPV4_IPV6",
    labels: {
        mykey: "myvalue",
    },
});
import pulumi
import pulumi_gcp as gcp

network1 = gcp.compute.Network("network1",
    name="network1",
    auto_create_subnetworks=False)
ha_gateway1 = gcp.compute.HaVpnGateway("ha_gateway1",
    region="us-central1",
    name="ha-vpn-1",
    network=network1.id,
    stack_type="IPV4_IPV6",
    labels={
        "mykey": "myvalue",
    })
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		network1, err := compute.NewNetwork(ctx, "network1", &compute.NetworkArgs{
			Name:                  pulumi.String("network1"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewHaVpnGateway(ctx, "ha_gateway1", &compute.HaVpnGatewayArgs{
			Region:    pulumi.String("us-central1"),
			Name:      pulumi.String("ha-vpn-1"),
			Network:   network1.ID(),
			StackType: pulumi.String("IPV4_IPV6"),
			Labels: pulumi.StringMap{
				"mykey": pulumi.String("myvalue"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var network1 = new Gcp.Compute.Network("network1", new()
    {
        Name = "network1",
        AutoCreateSubnetworks = false,
    });

    var haGateway1 = new Gcp.Compute.HaVpnGateway("ha_gateway1", new()
    {
        Region = "us-central1",
        Name = "ha-vpn-1",
        Network = network1.Id,
        StackType = "IPV4_IPV6",
        Labels = 
        {
            { "mykey", "myvalue" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.HaVpnGateway;
import com.pulumi.gcp.compute.HaVpnGatewayArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var network1 = new Network("network1", NetworkArgs.builder()
            .name("network1")
            .autoCreateSubnetworks(false)
            .build());

        var haGateway1 = new HaVpnGateway("haGateway1", HaVpnGatewayArgs.builder()
            .region("us-central1")
            .name("ha-vpn-1")
            .network(network1.id())
            .stackType("IPV4_IPV6")
            .labels(Map.of("mykey", "myvalue"))
            .build());

    }
}
resources:
  haGateway1:
    type: gcp:compute:HaVpnGateway
    name: ha_gateway1
    properties:
      region: us-central1
      name: ha-vpn-1
      network: ${network1.id}
      stackType: IPV4_IPV6
      labels:
        mykey: myvalue
  network1:
    type: gcp:compute:Network
    properties:
      name: network1
      autoCreateSubnetworks: false

The stackType property controls which IP protocols the gateway interfaces support. Setting it to IPV4_IPV6 enables dual-stack operation, allowing you to establish VPN tunnels over either IPv4 or IPv6. The labels property adds metadata for organization and cost tracking.

Attach to Cloud Interconnect for encrypted hybrid connectivity

Organizations with dedicated Cloud Interconnect circuits can layer IPsec encryption over the physical connection by attaching the VPN gateway to Interconnect attachments.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const network = new gcp.compute.Network("network", {
    name: "test-network",
    autoCreateSubnetworks: false,
});
const address1 = new gcp.compute.Address("address1", {
    name: "test-address1",
    addressType: "INTERNAL",
    purpose: "IPSEC_INTERCONNECT",
    address: "192.168.1.0",
    prefixLength: 29,
    network: network.selfLink,
});
const router = new gcp.compute.Router("router", {
    name: "test-router",
    network: network.name,
    encryptedInterconnectRouter: true,
    bgp: {
        asn: 16550,
    },
});
const attachment1 = new gcp.compute.InterconnectAttachment("attachment1", {
    name: "test-interconnect-attachment1",
    edgeAvailabilityDomain: "AVAILABILITY_DOMAIN_1",
    type: "PARTNER",
    router: router.id,
    encryption: "IPSEC",
    ipsecInternalAddresses: [address1.selfLink],
});
const address2 = new gcp.compute.Address("address2", {
    name: "test-address2",
    addressType: "INTERNAL",
    purpose: "IPSEC_INTERCONNECT",
    address: "192.168.2.0",
    prefixLength: 29,
    network: network.selfLink,
});
const attachment2 = new gcp.compute.InterconnectAttachment("attachment2", {
    name: "test-interconnect-attachment2",
    edgeAvailabilityDomain: "AVAILABILITY_DOMAIN_2",
    type: "PARTNER",
    router: router.id,
    encryption: "IPSEC",
    ipsecInternalAddresses: [address2.selfLink],
});
const vpn_gateway = new gcp.compute.HaVpnGateway("vpn-gateway", {
    name: "test-ha-vpngw",
    network: network.id,
    vpnInterfaces: [
        {
            id: 0,
            interconnectAttachment: attachment1.selfLink,
        },
        {
            id: 1,
            interconnectAttachment: attachment2.selfLink,
        },
    ],
});
import pulumi
import pulumi_gcp as gcp

network = gcp.compute.Network("network",
    name="test-network",
    auto_create_subnetworks=False)
address1 = gcp.compute.Address("address1",
    name="test-address1",
    address_type="INTERNAL",
    purpose="IPSEC_INTERCONNECT",
    address="192.168.1.0",
    prefix_length=29,
    network=network.self_link)
router = gcp.compute.Router("router",
    name="test-router",
    network=network.name,
    encrypted_interconnect_router=True,
    bgp={
        "asn": 16550,
    })
attachment1 = gcp.compute.InterconnectAttachment("attachment1",
    name="test-interconnect-attachment1",
    edge_availability_domain="AVAILABILITY_DOMAIN_1",
    type="PARTNER",
    router=router.id,
    encryption="IPSEC",
    ipsec_internal_addresses=[address1.self_link])
address2 = gcp.compute.Address("address2",
    name="test-address2",
    address_type="INTERNAL",
    purpose="IPSEC_INTERCONNECT",
    address="192.168.2.0",
    prefix_length=29,
    network=network.self_link)
attachment2 = gcp.compute.InterconnectAttachment("attachment2",
    name="test-interconnect-attachment2",
    edge_availability_domain="AVAILABILITY_DOMAIN_2",
    type="PARTNER",
    router=router.id,
    encryption="IPSEC",
    ipsec_internal_addresses=[address2.self_link])
vpn_gateway = gcp.compute.HaVpnGateway("vpn-gateway",
    name="test-ha-vpngw",
    network=network.id,
    vpn_interfaces=[
        {
            "id": 0,
            "interconnect_attachment": attachment1.self_link,
        },
        {
            "id": 1,
            "interconnect_attachment": attachment2.self_link,
        },
    ])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		network, err := compute.NewNetwork(ctx, "network", &compute.NetworkArgs{
			Name:                  pulumi.String("test-network"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		address1, err := compute.NewAddress(ctx, "address1", &compute.AddressArgs{
			Name:         pulumi.String("test-address1"),
			AddressType:  pulumi.String("INTERNAL"),
			Purpose:      pulumi.String("IPSEC_INTERCONNECT"),
			Address:      pulumi.String("192.168.1.0"),
			PrefixLength: pulumi.Int(29),
			Network:      network.SelfLink,
		})
		if err != nil {
			return err
		}
		router, err := compute.NewRouter(ctx, "router", &compute.RouterArgs{
			Name:                        pulumi.String("test-router"),
			Network:                     network.Name,
			EncryptedInterconnectRouter: pulumi.Bool(true),
			Bgp: &compute.RouterBgpArgs{
				Asn: pulumi.Int(16550),
			},
		})
		if err != nil {
			return err
		}
		attachment1, err := compute.NewInterconnectAttachment(ctx, "attachment1", &compute.InterconnectAttachmentArgs{
			Name:                   pulumi.String("test-interconnect-attachment1"),
			EdgeAvailabilityDomain: pulumi.String("AVAILABILITY_DOMAIN_1"),
			Type:                   pulumi.String("PARTNER"),
			Router:                 router.ID(),
			Encryption:             pulumi.String("IPSEC"),
			IpsecInternalAddresses: pulumi.StringArray{
				address1.SelfLink,
			},
		})
		if err != nil {
			return err
		}
		address2, err := compute.NewAddress(ctx, "address2", &compute.AddressArgs{
			Name:         pulumi.String("test-address2"),
			AddressType:  pulumi.String("INTERNAL"),
			Purpose:      pulumi.String("IPSEC_INTERCONNECT"),
			Address:      pulumi.String("192.168.2.0"),
			PrefixLength: pulumi.Int(29),
			Network:      network.SelfLink,
		})
		if err != nil {
			return err
		}
		attachment2, err := compute.NewInterconnectAttachment(ctx, "attachment2", &compute.InterconnectAttachmentArgs{
			Name:                   pulumi.String("test-interconnect-attachment2"),
			EdgeAvailabilityDomain: pulumi.String("AVAILABILITY_DOMAIN_2"),
			Type:                   pulumi.String("PARTNER"),
			Router:                 router.ID(),
			Encryption:             pulumi.String("IPSEC"),
			IpsecInternalAddresses: pulumi.StringArray{
				address2.SelfLink,
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewHaVpnGateway(ctx, "vpn-gateway", &compute.HaVpnGatewayArgs{
			Name:    pulumi.String("test-ha-vpngw"),
			Network: network.ID(),
			VpnInterfaces: compute.HaVpnGatewayVpnInterfaceArray{
				&compute.HaVpnGatewayVpnInterfaceArgs{
					Id:                     pulumi.Int(0),
					InterconnectAttachment: attachment1.SelfLink,
				},
				&compute.HaVpnGatewayVpnInterfaceArgs{
					Id:                     pulumi.Int(1),
					InterconnectAttachment: attachment2.SelfLink,
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var network = new Gcp.Compute.Network("network", new()
    {
        Name = "test-network",
        AutoCreateSubnetworks = false,
    });

    var address1 = new Gcp.Compute.Address("address1", new()
    {
        Name = "test-address1",
        AddressType = "INTERNAL",
        Purpose = "IPSEC_INTERCONNECT",
        IPAddress = "192.168.1.0",
        PrefixLength = 29,
        Network = network.SelfLink,
    });

    var router = new Gcp.Compute.Router("router", new()
    {
        Name = "test-router",
        Network = network.Name,
        EncryptedInterconnectRouter = true,
        Bgp = new Gcp.Compute.Inputs.RouterBgpArgs
        {
            Asn = 16550,
        },
    });

    var attachment1 = new Gcp.Compute.InterconnectAttachment("attachment1", new()
    {
        Name = "test-interconnect-attachment1",
        EdgeAvailabilityDomain = "AVAILABILITY_DOMAIN_1",
        Type = "PARTNER",
        Router = router.Id,
        Encryption = "IPSEC",
        IpsecInternalAddresses = new[]
        {
            address1.SelfLink,
        },
    });

    var address2 = new Gcp.Compute.Address("address2", new()
    {
        Name = "test-address2",
        AddressType = "INTERNAL",
        Purpose = "IPSEC_INTERCONNECT",
        IPAddress = "192.168.2.0",
        PrefixLength = 29,
        Network = network.SelfLink,
    });

    var attachment2 = new Gcp.Compute.InterconnectAttachment("attachment2", new()
    {
        Name = "test-interconnect-attachment2",
        EdgeAvailabilityDomain = "AVAILABILITY_DOMAIN_2",
        Type = "PARTNER",
        Router = router.Id,
        Encryption = "IPSEC",
        IpsecInternalAddresses = new[]
        {
            address2.SelfLink,
        },
    });

    var vpn_gateway = new Gcp.Compute.HaVpnGateway("vpn-gateway", new()
    {
        Name = "test-ha-vpngw",
        Network = network.Id,
        VpnInterfaces = new[]
        {
            new Gcp.Compute.Inputs.HaVpnGatewayVpnInterfaceArgs
            {
                Id = 0,
                InterconnectAttachment = attachment1.SelfLink,
            },
            new Gcp.Compute.Inputs.HaVpnGatewayVpnInterfaceArgs
            {
                Id = 1,
                InterconnectAttachment = attachment2.SelfLink,
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Address;
import com.pulumi.gcp.compute.AddressArgs;
import com.pulumi.gcp.compute.Router;
import com.pulumi.gcp.compute.RouterArgs;
import com.pulumi.gcp.compute.inputs.RouterBgpArgs;
import com.pulumi.gcp.compute.InterconnectAttachment;
import com.pulumi.gcp.compute.InterconnectAttachmentArgs;
import com.pulumi.gcp.compute.HaVpnGateway;
import com.pulumi.gcp.compute.HaVpnGatewayArgs;
import com.pulumi.gcp.compute.inputs.HaVpnGatewayVpnInterfaceArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var network = new Network("network", NetworkArgs.builder()
            .name("test-network")
            .autoCreateSubnetworks(false)
            .build());

        var address1 = new Address("address1", AddressArgs.builder()
            .name("test-address1")
            .addressType("INTERNAL")
            .purpose("IPSEC_INTERCONNECT")
            .address("192.168.1.0")
            .prefixLength(29)
            .network(network.selfLink())
            .build());

        var router = new Router("router", RouterArgs.builder()
            .name("test-router")
            .network(network.name())
            .encryptedInterconnectRouter(true)
            .bgp(RouterBgpArgs.builder()
                .asn(16550)
                .build())
            .build());

        var attachment1 = new InterconnectAttachment("attachment1", InterconnectAttachmentArgs.builder()
            .name("test-interconnect-attachment1")
            .edgeAvailabilityDomain("AVAILABILITY_DOMAIN_1")
            .type("PARTNER")
            .router(router.id())
            .encryption("IPSEC")
            .ipsecInternalAddresses(address1.selfLink())
            .build());

        var address2 = new Address("address2", AddressArgs.builder()
            .name("test-address2")
            .addressType("INTERNAL")
            .purpose("IPSEC_INTERCONNECT")
            .address("192.168.2.0")
            .prefixLength(29)
            .network(network.selfLink())
            .build());

        var attachment2 = new InterconnectAttachment("attachment2", InterconnectAttachmentArgs.builder()
            .name("test-interconnect-attachment2")
            .edgeAvailabilityDomain("AVAILABILITY_DOMAIN_2")
            .type("PARTNER")
            .router(router.id())
            .encryption("IPSEC")
            .ipsecInternalAddresses(address2.selfLink())
            .build());

        var vpn_gateway = new HaVpnGateway("vpn-gateway", HaVpnGatewayArgs.builder()
            .name("test-ha-vpngw")
            .network(network.id())
            .vpnInterfaces(            
                HaVpnGatewayVpnInterfaceArgs.builder()
                    .id(0)
                    .interconnectAttachment(attachment1.selfLink())
                    .build(),
                HaVpnGatewayVpnInterfaceArgs.builder()
                    .id(1)
                    .interconnectAttachment(attachment2.selfLink())
                    .build())
            .build());

    }
}
resources:
  vpn-gateway:
    type: gcp:compute:HaVpnGateway
    properties:
      name: test-ha-vpngw
      network: ${network.id}
      vpnInterfaces:
        - id: 0
          interconnectAttachment: ${attachment1.selfLink}
        - id: 1
          interconnectAttachment: ${attachment2.selfLink}
  attachment1:
    type: gcp:compute:InterconnectAttachment
    properties:
      name: test-interconnect-attachment1
      edgeAvailabilityDomain: AVAILABILITY_DOMAIN_1
      type: PARTNER
      router: ${router.id}
      encryption: IPSEC
      ipsecInternalAddresses:
        - ${address1.selfLink}
  attachment2:
    type: gcp:compute:InterconnectAttachment
    properties:
      name: test-interconnect-attachment2
      edgeAvailabilityDomain: AVAILABILITY_DOMAIN_2
      type: PARTNER
      router: ${router.id}
      encryption: IPSEC
      ipsecInternalAddresses:
        - ${address2.selfLink}
  address1:
    type: gcp:compute:Address
    properties:
      name: test-address1
      addressType: INTERNAL
      purpose: IPSEC_INTERCONNECT
      address: 192.168.1.0
      prefixLength: 29
      network: ${network.selfLink}
  address2:
    type: gcp:compute:Address
    properties:
      name: test-address2
      addressType: INTERNAL
      purpose: IPSEC_INTERCONNECT
      address: 192.168.2.0
      prefixLength: 29
      network: ${network.selfLink}
  router:
    type: gcp:compute:Router
    properties:
      name: test-router
      network: ${network.name}
      encryptedInterconnectRouter: true
      bgp:
        asn: 16550
  network:
    type: gcp:compute:Network
    properties:
      name: test-network
      autoCreateSubnetworks: false

The vpnInterfaces property maps each gateway interface to an Interconnect attachment, enabling encrypted traffic over your dedicated circuits. Each attachment requires an internal IP address range with IPSEC_INTERCONNECT purpose. The router must have encryptedInterconnectRouter enabled to support this configuration. This setup combines the bandwidth and predictability of Interconnect with the security of IPsec encryption.

Beyond these examples

These snippets focus on specific HA VPN gateway features: basic gateway creation, dual-stack IPv4/IPv6 configuration, and Cloud Interconnect integration. They’re intentionally minimal rather than full VPN solutions.

The examples may reference pre-existing infrastructure such as VPC networks, Cloud Interconnect circuits and attachments, and Cloud Router with BGP configuration. They focus on gateway provisioning rather than complete VPN connectivity.

To keep things focused, common VPN patterns are omitted, including:

  • VPN tunnel configuration (separate resource)
  • External VPN gateway definitions for peer connectivity
  • BGP session setup and route exchange
  • Firewall rules for VPN traffic

These omissions are intentional: the goal is to illustrate how each gateway feature is wired, not provide drop-in VPN modules. See the HA VPN Gateway resource reference for all available configuration options.

Let's configure GCP HA VPN Gateways

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Naming
What are the naming requirements for an HA VPN gateway?
The name must be 1-63 characters long, start with a lowercase letter, and match the regex a-z?. This means only lowercase letters, digits, and dashes are allowed, and the name cannot end with a dash.
What's required to create a basic HA VPN gateway?
You need to specify name, region, and network. The gateway defaults to IPV4_ONLY stack type if not specified.
Immutability & Updates
What properties can't be changed after creating an HA VPN gateway?
The following properties are immutable and require resource replacement if changed: name, network, region, vpnInterfaces, stackType, gatewayIpVersion, and description. Only labels can be modified after creation.
IP Protocol Support
What's the difference between stackType and gatewayIpVersion?
Both control IP protocol support but serve different purposes. stackType identifies which IP protocols are enabled on the gateway (IPV4_ONLY, IPV4_IPV6, or IPV6_ONLY), while gatewayIpVersion specifies the IP family for the gateway interface IPs (IPV4 or IPV6). Both default to IPv4 if not specified.
How do I enable IPv6 support for my HA VPN gateway?
Set stackType to IPV4_IPV6 (for dual-stack) or IPV6_ONLY when creating the gateway. This property is immutable, so you must configure it at creation time.
What are the default IP protocol settings?
By default, stackType is IPV4_ONLY and gatewayIpVersion is IPV4, meaning the gateway only supports IPv4 traffic.
Labels & Metadata
Why aren't all my labels showing up in the labels field?
The labels field is non-authoritative and only manages labels defined in your Pulumi configuration. To see all labels on the resource (including those added by other clients or services), use the effectiveLabels output property.
Advanced Use Cases
How do I use an HA VPN gateway with encrypted interconnect attachments?
Configure vpnInterfaces with interconnectAttachment references pointing to your IPSEC-encrypted interconnect attachments. Each interface needs an id and the interconnectAttachment self-link.

Using a different cloud?

Explore networking guides for other cloud providers: