Configure GCP Network Connectivity Hub

The gcp:networkconnectivity/hub:Hub resource, part of the Pulumi GCP provider, defines a Network Connectivity Center hub that serves as the central routing point for connecting VPC spokes and managing inter-spoke connectivity. This guide focuses on three capabilities: basic hub creation with labels, Private Service Connect transitivity, and preset topology configuration.

Hubs are global resources that require a GCP project with Network Connectivity Center API enabled. VPC spokes are attached separately. The examples are intentionally small. Combine them with your own spoke attachments and routing policies.

Create a hub with labels for organization

Most deployments start with a basic hub that serves as the central point for connecting VPC spokes.

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

const primary = new gcp.networkconnectivity.Hub("primary", {
    name: "basic",
    description: "A sample hub",
    labels: {
        "label-one": "value-one",
    },
});
import pulumi
import pulumi_gcp as gcp

primary = gcp.networkconnectivity.Hub("primary",
    name="basic",
    description="A sample hub",
    labels={
        "label-one": "value-one",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networkconnectivity.NewHub(ctx, "primary", &networkconnectivity.HubArgs{
			Name:        pulumi.String("basic"),
			Description: pulumi.String("A sample hub"),
			Labels: pulumi.StringMap{
				"label-one": pulumi.String("value-one"),
			},
		})
		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 primary = new Gcp.NetworkConnectivity.Hub("primary", new()
    {
        Name = "basic",
        Description = "A sample hub",
        Labels = 
        {
            { "label-one", "value-one" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkconnectivity.Hub;
import com.pulumi.gcp.networkconnectivity.HubArgs;
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 primary = new Hub("primary", HubArgs.builder()
            .name("basic")
            .description("A sample hub")
            .labels(Map.of("label-one", "value-one"))
            .build());

    }
}
resources:
  primary:
    type: gcp:networkconnectivity:Hub
    properties:
      name: basic
      description: A sample hub
      labels:
        label-one: value-one

The name property sets a unique identifier for the hub within your project. The description provides human-readable context. Labels help organize hubs across projects and teams for cost tracking and resource management. Without additional configuration, the hub defaults to MESH topology with PRESET policy mode.

Enable Private Service Connect transitivity

When VPC spokes need to access Private Service Connect endpoints across the hub, enabling PSC transitivity allows endpoints in one spoke to be reached from other spokes.

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

const primary = new gcp.networkconnectivity.Hub("primary", {
    name: "basic",
    description: "A sample hub with Private Service Connect transitivity is enabled",
    exportPsc: true,
});
import pulumi
import pulumi_gcp as gcp

primary = gcp.networkconnectivity.Hub("primary",
    name="basic",
    description="A sample hub with Private Service Connect transitivity is enabled",
    export_psc=True)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networkconnectivity.NewHub(ctx, "primary", &networkconnectivity.HubArgs{
			Name:        pulumi.String("basic"),
			Description: pulumi.String("A sample hub with Private Service Connect transitivity is enabled"),
			ExportPsc:   pulumi.Bool(true),
		})
		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 primary = new Gcp.NetworkConnectivity.Hub("primary", new()
    {
        Name = "basic",
        Description = "A sample hub with Private Service Connect transitivity is enabled",
        ExportPsc = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkconnectivity.Hub;
import com.pulumi.gcp.networkconnectivity.HubArgs;
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 primary = new Hub("primary", HubArgs.builder()
            .name("basic")
            .description("A sample hub with Private Service Connect transitivity is enabled")
            .exportPsc(true)
            .build());

    }
}
resources:
  primary:
    type: gcp:networkconnectivity:Hub
    properties:
      name: basic
      description: A sample hub with Private Service Connect transitivity is enabled
      exportPsc: true

The exportPsc property controls whether Private Service Connect endpoints in attached VPC spokes become accessible to other spokes through the hub. When set to true, the hub acts as a transit point for PSC traffic, enabling cross-spoke endpoint access. This defaults to false if not specified.

Configure star topology for hub-and-spoke routing

Star topology routes all traffic through the hub, preventing direct spoke-to-spoke communication and centralizing traffic inspection.

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

const primary = new gcp.networkconnectivity.Hub("primary", {
    name: "star",
    description: "A sample star hub",
    labels: {
        "label-one": "value-one",
    },
    presetTopology: "STAR",
});
import pulumi
import pulumi_gcp as gcp

primary = gcp.networkconnectivity.Hub("primary",
    name="star",
    description="A sample star hub",
    labels={
        "label-one": "value-one",
    },
    preset_topology="STAR")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networkconnectivity.NewHub(ctx, "primary", &networkconnectivity.HubArgs{
			Name:        pulumi.String("star"),
			Description: pulumi.String("A sample star hub"),
			Labels: pulumi.StringMap{
				"label-one": pulumi.String("value-one"),
			},
			PresetTopology: pulumi.String("STAR"),
		})
		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 primary = new Gcp.NetworkConnectivity.Hub("primary", new()
    {
        Name = "star",
        Description = "A sample star hub",
        Labels = 
        {
            { "label-one", "value-one" },
        },
        PresetTopology = "STAR",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkconnectivity.Hub;
import com.pulumi.gcp.networkconnectivity.HubArgs;
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 primary = new Hub("primary", HubArgs.builder()
            .name("star")
            .description("A sample star hub")
            .labels(Map.of("label-one", "value-one"))
            .presetTopology("STAR")
            .build());

    }
}
resources:
  primary:
    type: gcp:networkconnectivity:Hub
    properties:
      name: star
      description: A sample star hub
      labels:
        label-one: value-one
      presetTopology: STAR

The presetTopology property defines the routing pattern. STAR topology forces all inter-spoke traffic through the hub, enabling centralized inspection and control. This contrasts with MESH topology, where spokes can communicate directly. The topology is immutable after creation.

Set policy mode with preset topology

Policy mode determines whether the hub uses preset topologies or custom routing policies.

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

const primary = new gcp.networkconnectivity.Hub("primary", {
    name: "policy",
    description: "A sample hub with PRESET policy_mode and STAR topology",
    policyMode: "PRESET",
    presetTopology: "STAR",
    labels: {
        "label-one": "value-one",
    },
});
import pulumi
import pulumi_gcp as gcp

primary = gcp.networkconnectivity.Hub("primary",
    name="policy",
    description="A sample hub with PRESET policy_mode and STAR topology",
    policy_mode="PRESET",
    preset_topology="STAR",
    labels={
        "label-one": "value-one",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := networkconnectivity.NewHub(ctx, "primary", &networkconnectivity.HubArgs{
			Name:           pulumi.String("policy"),
			Description:    pulumi.String("A sample hub with PRESET policy_mode and STAR topology"),
			PolicyMode:     pulumi.String("PRESET"),
			PresetTopology: pulumi.String("STAR"),
			Labels: pulumi.StringMap{
				"label-one": pulumi.String("value-one"),
			},
		})
		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 primary = new Gcp.NetworkConnectivity.Hub("primary", new()
    {
        Name = "policy",
        Description = "A sample hub with PRESET policy_mode and STAR topology",
        PolicyMode = "PRESET",
        PresetTopology = "STAR",
        Labels = 
        {
            { "label-one", "value-one" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkconnectivity.Hub;
import com.pulumi.gcp.networkconnectivity.HubArgs;
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 primary = new Hub("primary", HubArgs.builder()
            .name("policy")
            .description("A sample hub with PRESET policy_mode and STAR topology")
            .policyMode("PRESET")
            .presetTopology("STAR")
            .labels(Map.of("label-one", "value-one"))
            .build());

    }
}
resources:
  primary:
    type: gcp:networkconnectivity:Hub
    properties:
      name: policy
      description: A sample hub with PRESET policy_mode and STAR topology
      policyMode: PRESET
      presetTopology: STAR
      labels:
        label-one: value-one

The policyMode property controls routing behavior. PRESET mode uses predefined topologies (MESH or STAR) specified by presetTopology. CUSTOM mode allows user-defined routing policies. When policyMode is PRESET and presetTopology is STAR, the hub enforces hub-and-spoke routing patterns. Both properties are immutable after creation.

Beyond these examples

These snippets focus on specific hub-level features: hub creation and labeling, Private Service Connect transitivity, and preset topologies. They’re intentionally minimal rather than full network architectures.

The examples assume pre-existing infrastructure such as a GCP project with Network Connectivity Center API enabled. They focus on configuring the hub rather than provisioning VPC spokes or routing policies.

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

  • VPC spoke attachment and configuration
  • Custom routing policies (policyMode: CUSTOM)
  • Hybrid inspection topology (HYBRID_INSPECTION)
  • Hub deletion and lifecycle management

These omissions are intentional: the goal is to illustrate how each hub feature is wired, not provide drop-in network modules. See the Network Connectivity Hub resource reference for all available configuration options.

Let's configure GCP Network Connectivity Hub

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Topology & Policy Configuration
What's the difference between MESH and STAR topologies?
MESH topology allows any-to-any connectivity between spokes, while STAR topology routes all traffic through the hub. HYBRID_INSPECTION is also available for inspection use cases. These topologies are available when policyMode is set to PRESET.
How does policyMode affect presetTopology?
When policyMode is PRESET, you can specify MESH or STAR topology (defaults to MESH). When policyMode is CUSTOM, presetTopology is automatically set to PRESET_TOPOLOGY_UNSPECIFIED and isn’t used.
What are the default values for policy and topology?
If unspecified, policyMode defaults to PRESET. When policyMode is PRESET and presetTopology is unspecified, the topology defaults to MESH.
Immutability & Lifecycle
What properties can't be changed after creating a hub?
The name, policyMode, presetTopology, and project properties are immutable. Changing any of these requires destroying and recreating the hub.
Private Service Connect
What does enabling exportPsc do?
Setting exportPsc to true enables Private Service Connect transitivity, making PSC endpoints in VPC spokes accessible to other VPC spokes attached to the hub. The default value is false.
Labels & Metadata
Why are my labels different than what I configured?
The labels field is non-authoritative and only manages labels present in your configuration. Use effectiveLabels to see all labels on the resource, including those set by other clients and services.

Using a different cloud?

Explore networking guides for other cloud providers: