The gcp:networkservices/tcpRoute:TcpRoute resource, part of the Pulumi GCP provider, defines how TCP traffic is routed by Mesh or Gateway resources: match criteria, destination services, and connection behavior. This guide focuses on three capabilities: address and port-based routing, connection timeout configuration, and mesh and gateway attachment.
TcpRoute resources reference backend services and attach to either Mesh or Gateway resources that must exist separately. The examples are intentionally small. Combine them with your own backend services and routing infrastructure.
Route TCP traffic with address and port matching
Most TCP routing starts by defining match criteria and directing traffic to backend services.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
name: "backend-service-health-check",
requestPath: "/",
checkIntervalSec: 1,
timeoutSec: 1,
});
const _default = new gcp.compute.BackendService("default", {
name: "my-backend-service",
healthChecks: defaultHttpHealthCheck.id,
});
const defaultTcpRoute = new gcp.networkservices.TcpRoute("default", {
name: "my-tcp-route",
labels: {
foo: "bar",
},
description: "my description",
rules: [{
matches: [{
address: "10.0.0.1/32",
port: "8081",
}],
action: {
destinations: [{
serviceName: _default.id,
weight: 1,
}],
originalDestination: false,
},
}],
});
import pulumi
import pulumi_gcp as gcp
default_http_health_check = gcp.compute.HttpHealthCheck("default",
name="backend-service-health-check",
request_path="/",
check_interval_sec=1,
timeout_sec=1)
default = gcp.compute.BackendService("default",
name="my-backend-service",
health_checks=default_http_health_check.id)
default_tcp_route = gcp.networkservices.TcpRoute("default",
name="my-tcp-route",
labels={
"foo": "bar",
},
description="my description",
rules=[{
"matches": [{
"address": "10.0.0.1/32",
"port": "8081",
}],
"action": {
"destinations": [{
"service_name": default.id,
"weight": 1,
}],
"original_destination": False,
},
}])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkservices"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
Name: pulumi.String("backend-service-health-check"),
RequestPath: pulumi.String("/"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
})
if err != nil {
return err
}
_default, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("my-backend-service"),
HealthChecks: defaultHttpHealthCheck.ID(),
})
if err != nil {
return err
}
_, err = networkservices.NewTcpRoute(ctx, "default", &networkservices.TcpRouteArgs{
Name: pulumi.String("my-tcp-route"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
Rules: networkservices.TcpRouteRuleArray{
&networkservices.TcpRouteRuleArgs{
Matches: networkservices.TcpRouteRuleMatchArray{
&networkservices.TcpRouteRuleMatchArgs{
Address: pulumi.String("10.0.0.1/32"),
Port: pulumi.String("8081"),
},
},
Action: &networkservices.TcpRouteRuleActionArgs{
Destinations: networkservices.TcpRouteRuleActionDestinationArray{
&networkservices.TcpRouteRuleActionDestinationArgs{
ServiceName: _default.ID(),
Weight: pulumi.Int(1),
},
},
OriginalDestination: pulumi.Bool(false),
},
},
},
})
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 defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
{
Name = "backend-service-health-check",
RequestPath = "/",
CheckIntervalSec = 1,
TimeoutSec = 1,
});
var @default = new Gcp.Compute.BackendService("default", new()
{
Name = "my-backend-service",
HealthChecks = defaultHttpHealthCheck.Id,
});
var defaultTcpRoute = new Gcp.NetworkServices.TcpRoute("default", new()
{
Name = "my-tcp-route",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
Rules = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleArgs
{
Matches = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleMatchArgs
{
Address = "10.0.0.1/32",
Port = "8081",
},
},
Action = new Gcp.NetworkServices.Inputs.TcpRouteRuleActionArgs
{
Destinations = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleActionDestinationArgs
{
ServiceName = @default.Id,
Weight = 1,
},
},
OriginalDestination = false,
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.networkservices.TcpRoute;
import com.pulumi.gcp.networkservices.TcpRouteArgs;
import com.pulumi.gcp.networkservices.inputs.TcpRouteRuleArgs;
import com.pulumi.gcp.networkservices.inputs.TcpRouteRuleActionArgs;
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 defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
.name("backend-service-health-check")
.requestPath("/")
.checkIntervalSec(1)
.timeoutSec(1)
.build());
var default_ = new BackendService("default", BackendServiceArgs.builder()
.name("my-backend-service")
.healthChecks(defaultHttpHealthCheck.id())
.build());
var defaultTcpRoute = new TcpRoute("defaultTcpRoute", TcpRouteArgs.builder()
.name("my-tcp-route")
.labels(Map.of("foo", "bar"))
.description("my description")
.rules(TcpRouteRuleArgs.builder()
.matches(TcpRouteRuleMatchArgs.builder()
.address("10.0.0.1/32")
.port("8081")
.build())
.action(TcpRouteRuleActionArgs.builder()
.destinations(TcpRouteRuleActionDestinationArgs.builder()
.serviceName(default_.id())
.weight(1)
.build())
.originalDestination(false)
.build())
.build())
.build());
}
}
resources:
default:
type: gcp:compute:BackendService
properties:
name: my-backend-service
healthChecks: ${defaultHttpHealthCheck.id}
defaultHttpHealthCheck:
type: gcp:compute:HttpHealthCheck
name: default
properties:
name: backend-service-health-check
requestPath: /
checkIntervalSec: 1
timeoutSec: 1
defaultTcpRoute:
type: gcp:networkservices:TcpRoute
name: default
properties:
name: my-tcp-route
labels:
foo: bar
description: my description
rules:
- matches:
- address: 10.0.0.1/32
port: '8081'
action:
destinations:
- serviceName: ${default.id}
weight: 1
originalDestination: false
When a TCP connection arrives, the route evaluates the matches array to find the first rule where the source address and port match. The action.destinations array specifies which backend services receive the traffic, with weight controlling load distribution. The serviceName references a BackendService that handles the actual request processing.
Configure connection timeout behavior
Long-lived TCP connections need explicit timeout configuration to manage idle connections.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
name: "backend-service-health-check",
requestPath: "/",
checkIntervalSec: 1,
timeoutSec: 1,
});
const _default = new gcp.compute.BackendService("default", {
name: "my-backend-service",
healthChecks: defaultHttpHealthCheck.id,
});
const defaultTcpRoute = new gcp.networkservices.TcpRoute("default", {
name: "my-tcp-route",
labels: {
foo: "bar",
},
description: "my description",
rules: [{
action: {
destinations: [{
serviceName: _default.id,
weight: 1,
}],
originalDestination: false,
idleTimeout: "60s",
},
}],
});
import pulumi
import pulumi_gcp as gcp
default_http_health_check = gcp.compute.HttpHealthCheck("default",
name="backend-service-health-check",
request_path="/",
check_interval_sec=1,
timeout_sec=1)
default = gcp.compute.BackendService("default",
name="my-backend-service",
health_checks=default_http_health_check.id)
default_tcp_route = gcp.networkservices.TcpRoute("default",
name="my-tcp-route",
labels={
"foo": "bar",
},
description="my description",
rules=[{
"action": {
"destinations": [{
"service_name": default.id,
"weight": 1,
}],
"original_destination": False,
"idle_timeout": "60s",
},
}])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkservices"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
Name: pulumi.String("backend-service-health-check"),
RequestPath: pulumi.String("/"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
})
if err != nil {
return err
}
_default, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("my-backend-service"),
HealthChecks: defaultHttpHealthCheck.ID(),
})
if err != nil {
return err
}
_, err = networkservices.NewTcpRoute(ctx, "default", &networkservices.TcpRouteArgs{
Name: pulumi.String("my-tcp-route"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
Rules: networkservices.TcpRouteRuleArray{
&networkservices.TcpRouteRuleArgs{
Action: &networkservices.TcpRouteRuleActionArgs{
Destinations: networkservices.TcpRouteRuleActionDestinationArray{
&networkservices.TcpRouteRuleActionDestinationArgs{
ServiceName: _default.ID(),
Weight: pulumi.Int(1),
},
},
OriginalDestination: pulumi.Bool(false),
IdleTimeout: pulumi.String("60s"),
},
},
},
})
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 defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
{
Name = "backend-service-health-check",
RequestPath = "/",
CheckIntervalSec = 1,
TimeoutSec = 1,
});
var @default = new Gcp.Compute.BackendService("default", new()
{
Name = "my-backend-service",
HealthChecks = defaultHttpHealthCheck.Id,
});
var defaultTcpRoute = new Gcp.NetworkServices.TcpRoute("default", new()
{
Name = "my-tcp-route",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
Rules = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleArgs
{
Action = new Gcp.NetworkServices.Inputs.TcpRouteRuleActionArgs
{
Destinations = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleActionDestinationArgs
{
ServiceName = @default.Id,
Weight = 1,
},
},
OriginalDestination = false,
IdleTimeout = "60s",
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.networkservices.TcpRoute;
import com.pulumi.gcp.networkservices.TcpRouteArgs;
import com.pulumi.gcp.networkservices.inputs.TcpRouteRuleArgs;
import com.pulumi.gcp.networkservices.inputs.TcpRouteRuleActionArgs;
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 defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
.name("backend-service-health-check")
.requestPath("/")
.checkIntervalSec(1)
.timeoutSec(1)
.build());
var default_ = new BackendService("default", BackendServiceArgs.builder()
.name("my-backend-service")
.healthChecks(defaultHttpHealthCheck.id())
.build());
var defaultTcpRoute = new TcpRoute("defaultTcpRoute", TcpRouteArgs.builder()
.name("my-tcp-route")
.labels(Map.of("foo", "bar"))
.description("my description")
.rules(TcpRouteRuleArgs.builder()
.action(TcpRouteRuleActionArgs.builder()
.destinations(TcpRouteRuleActionDestinationArgs.builder()
.serviceName(default_.id())
.weight(1)
.build())
.originalDestination(false)
.idleTimeout("60s")
.build())
.build())
.build());
}
}
resources:
default:
type: gcp:compute:BackendService
properties:
name: my-backend-service
healthChecks: ${defaultHttpHealthCheck.id}
defaultHttpHealthCheck:
type: gcp:compute:HttpHealthCheck
name: default
properties:
name: backend-service-health-check
requestPath: /
checkIntervalSec: 1
timeoutSec: 1
defaultTcpRoute:
type: gcp:networkservices:TcpRoute
name: default
properties:
name: my-tcp-route
labels:
foo: bar
description: my description
rules:
- action:
destinations:
- serviceName: ${default.id}
weight: 1
originalDestination: false
idleTimeout: 60s
The idleTimeout property controls how long a TCP connection can remain idle before being closed. This prevents resource exhaustion from abandoned connections. The originalDestination flag determines whether the route preserves the original destination address or rewrites it to the backend service address.
Attach routes to service mesh infrastructure
Service mesh deployments apply routing rules across sidecar proxies for consistent traffic management.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
name: "backend-service-health-check",
requestPath: "/",
checkIntervalSec: 1,
timeoutSec: 1,
});
const _default = new gcp.compute.BackendService("default", {
name: "my-backend-service",
healthChecks: defaultHttpHealthCheck.id,
});
const defaultMesh = new gcp.networkservices.Mesh("default", {
name: "my-tcp-route",
labels: {
foo: "bar",
},
description: "my description",
});
const defaultTcpRoute = new gcp.networkservices.TcpRoute("default", {
name: "my-tcp-route",
labels: {
foo: "bar",
},
description: "my description",
meshes: [defaultMesh.id],
rules: [{
matches: [{
address: "10.0.0.1/32",
port: "8081",
}],
action: {
destinations: [{
serviceName: _default.id,
weight: 1,
}],
originalDestination: false,
},
}],
});
import pulumi
import pulumi_gcp as gcp
default_http_health_check = gcp.compute.HttpHealthCheck("default",
name="backend-service-health-check",
request_path="/",
check_interval_sec=1,
timeout_sec=1)
default = gcp.compute.BackendService("default",
name="my-backend-service",
health_checks=default_http_health_check.id)
default_mesh = gcp.networkservices.Mesh("default",
name="my-tcp-route",
labels={
"foo": "bar",
},
description="my description")
default_tcp_route = gcp.networkservices.TcpRoute("default",
name="my-tcp-route",
labels={
"foo": "bar",
},
description="my description",
meshes=[default_mesh.id],
rules=[{
"matches": [{
"address": "10.0.0.1/32",
"port": "8081",
}],
"action": {
"destinations": [{
"service_name": default.id,
"weight": 1,
}],
"original_destination": False,
},
}])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkservices"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
Name: pulumi.String("backend-service-health-check"),
RequestPath: pulumi.String("/"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
})
if err != nil {
return err
}
_default, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("my-backend-service"),
HealthChecks: defaultHttpHealthCheck.ID(),
})
if err != nil {
return err
}
defaultMesh, err := networkservices.NewMesh(ctx, "default", &networkservices.MeshArgs{
Name: pulumi.String("my-tcp-route"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
})
if err != nil {
return err
}
_, err = networkservices.NewTcpRoute(ctx, "default", &networkservices.TcpRouteArgs{
Name: pulumi.String("my-tcp-route"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
Meshes: pulumi.StringArray{
defaultMesh.ID(),
},
Rules: networkservices.TcpRouteRuleArray{
&networkservices.TcpRouteRuleArgs{
Matches: networkservices.TcpRouteRuleMatchArray{
&networkservices.TcpRouteRuleMatchArgs{
Address: pulumi.String("10.0.0.1/32"),
Port: pulumi.String("8081"),
},
},
Action: &networkservices.TcpRouteRuleActionArgs{
Destinations: networkservices.TcpRouteRuleActionDestinationArray{
&networkservices.TcpRouteRuleActionDestinationArgs{
ServiceName: _default.ID(),
Weight: pulumi.Int(1),
},
},
OriginalDestination: pulumi.Bool(false),
},
},
},
})
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 defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
{
Name = "backend-service-health-check",
RequestPath = "/",
CheckIntervalSec = 1,
TimeoutSec = 1,
});
var @default = new Gcp.Compute.BackendService("default", new()
{
Name = "my-backend-service",
HealthChecks = defaultHttpHealthCheck.Id,
});
var defaultMesh = new Gcp.NetworkServices.Mesh("default", new()
{
Name = "my-tcp-route",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
});
var defaultTcpRoute = new Gcp.NetworkServices.TcpRoute("default", new()
{
Name = "my-tcp-route",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
Meshes = new[]
{
defaultMesh.Id,
},
Rules = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleArgs
{
Matches = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleMatchArgs
{
Address = "10.0.0.1/32",
Port = "8081",
},
},
Action = new Gcp.NetworkServices.Inputs.TcpRouteRuleActionArgs
{
Destinations = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleActionDestinationArgs
{
ServiceName = @default.Id,
Weight = 1,
},
},
OriginalDestination = false,
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.networkservices.Mesh;
import com.pulumi.gcp.networkservices.MeshArgs;
import com.pulumi.gcp.networkservices.TcpRoute;
import com.pulumi.gcp.networkservices.TcpRouteArgs;
import com.pulumi.gcp.networkservices.inputs.TcpRouteRuleArgs;
import com.pulumi.gcp.networkservices.inputs.TcpRouteRuleActionArgs;
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 defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
.name("backend-service-health-check")
.requestPath("/")
.checkIntervalSec(1)
.timeoutSec(1)
.build());
var default_ = new BackendService("default", BackendServiceArgs.builder()
.name("my-backend-service")
.healthChecks(defaultHttpHealthCheck.id())
.build());
var defaultMesh = new Mesh("defaultMesh", MeshArgs.builder()
.name("my-tcp-route")
.labels(Map.of("foo", "bar"))
.description("my description")
.build());
var defaultTcpRoute = new TcpRoute("defaultTcpRoute", TcpRouteArgs.builder()
.name("my-tcp-route")
.labels(Map.of("foo", "bar"))
.description("my description")
.meshes(defaultMesh.id())
.rules(TcpRouteRuleArgs.builder()
.matches(TcpRouteRuleMatchArgs.builder()
.address("10.0.0.1/32")
.port("8081")
.build())
.action(TcpRouteRuleActionArgs.builder()
.destinations(TcpRouteRuleActionDestinationArgs.builder()
.serviceName(default_.id())
.weight(1)
.build())
.originalDestination(false)
.build())
.build())
.build());
}
}
resources:
default:
type: gcp:compute:BackendService
properties:
name: my-backend-service
healthChecks: ${defaultHttpHealthCheck.id}
defaultHttpHealthCheck:
type: gcp:compute:HttpHealthCheck
name: default
properties:
name: backend-service-health-check
requestPath: /
checkIntervalSec: 1
timeoutSec: 1
defaultMesh:
type: gcp:networkservices:Mesh
name: default
properties:
name: my-tcp-route
labels:
foo: bar
description: my description
defaultTcpRoute:
type: gcp:networkservices:TcpRoute
name: default
properties:
name: my-tcp-route
labels:
foo: bar
description: my description
meshes:
- ${defaultMesh.id}
rules:
- matches:
- address: 10.0.0.1/32
port: '8081'
action:
destinations:
- serviceName: ${default.id}
weight: 1
originalDestination: false
The meshes property attaches the route to a Mesh resource, making the routing rules available to all services in the mesh. The Mesh must be of type SIDECAR. Traffic matching the rules flows through the mesh’s sidecar proxies to the specified backend services.
Attach routes to gateway infrastructure
Gateway-based deployments route ingress traffic through centralized infrastructure at the network edge.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
name: "backend-service-health-check",
requestPath: "/",
checkIntervalSec: 1,
timeoutSec: 1,
});
const _default = new gcp.compute.BackendService("default", {
name: "my-backend-service",
healthChecks: defaultHttpHealthCheck.id,
});
const defaultGateway = new gcp.networkservices.Gateway("default", {
name: "my-tcp-route",
labels: {
foo: "bar",
},
description: "my description",
scope: "my-scope",
type: "OPEN_MESH",
ports: [443],
});
const defaultTcpRoute = new gcp.networkservices.TcpRoute("default", {
name: "my-tcp-route",
labels: {
foo: "bar",
},
description: "my description",
gateways: [defaultGateway.id],
rules: [{
matches: [{
address: "10.0.0.1/32",
port: "8081",
}],
action: {
destinations: [{
serviceName: _default.id,
weight: 1,
}],
originalDestination: false,
},
}],
});
import pulumi
import pulumi_gcp as gcp
default_http_health_check = gcp.compute.HttpHealthCheck("default",
name="backend-service-health-check",
request_path="/",
check_interval_sec=1,
timeout_sec=1)
default = gcp.compute.BackendService("default",
name="my-backend-service",
health_checks=default_http_health_check.id)
default_gateway = gcp.networkservices.Gateway("default",
name="my-tcp-route",
labels={
"foo": "bar",
},
description="my description",
scope="my-scope",
type="OPEN_MESH",
ports=[443])
default_tcp_route = gcp.networkservices.TcpRoute("default",
name="my-tcp-route",
labels={
"foo": "bar",
},
description="my description",
gateways=[default_gateway.id],
rules=[{
"matches": [{
"address": "10.0.0.1/32",
"port": "8081",
}],
"action": {
"destinations": [{
"service_name": default.id,
"weight": 1,
}],
"original_destination": False,
},
}])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networkservices"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
Name: pulumi.String("backend-service-health-check"),
RequestPath: pulumi.String("/"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
})
if err != nil {
return err
}
_default, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("my-backend-service"),
HealthChecks: defaultHttpHealthCheck.ID(),
})
if err != nil {
return err
}
defaultGateway, err := networkservices.NewGateway(ctx, "default", &networkservices.GatewayArgs{
Name: pulumi.String("my-tcp-route"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
Scope: pulumi.String("my-scope"),
Type: pulumi.String("OPEN_MESH"),
Ports: pulumi.IntArray{
pulumi.Int(443),
},
})
if err != nil {
return err
}
_, err = networkservices.NewTcpRoute(ctx, "default", &networkservices.TcpRouteArgs{
Name: pulumi.String("my-tcp-route"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
Gateways: pulumi.StringArray{
defaultGateway.ID(),
},
Rules: networkservices.TcpRouteRuleArray{
&networkservices.TcpRouteRuleArgs{
Matches: networkservices.TcpRouteRuleMatchArray{
&networkservices.TcpRouteRuleMatchArgs{
Address: pulumi.String("10.0.0.1/32"),
Port: pulumi.String("8081"),
},
},
Action: &networkservices.TcpRouteRuleActionArgs{
Destinations: networkservices.TcpRouteRuleActionDestinationArray{
&networkservices.TcpRouteRuleActionDestinationArgs{
ServiceName: _default.ID(),
Weight: pulumi.Int(1),
},
},
OriginalDestination: pulumi.Bool(false),
},
},
},
})
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 defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
{
Name = "backend-service-health-check",
RequestPath = "/",
CheckIntervalSec = 1,
TimeoutSec = 1,
});
var @default = new Gcp.Compute.BackendService("default", new()
{
Name = "my-backend-service",
HealthChecks = defaultHttpHealthCheck.Id,
});
var defaultGateway = new Gcp.NetworkServices.Gateway("default", new()
{
Name = "my-tcp-route",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
Scope = "my-scope",
Type = "OPEN_MESH",
Ports = new[]
{
443,
},
});
var defaultTcpRoute = new Gcp.NetworkServices.TcpRoute("default", new()
{
Name = "my-tcp-route",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
Gateways = new[]
{
defaultGateway.Id,
},
Rules = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleArgs
{
Matches = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleMatchArgs
{
Address = "10.0.0.1/32",
Port = "8081",
},
},
Action = new Gcp.NetworkServices.Inputs.TcpRouteRuleActionArgs
{
Destinations = new[]
{
new Gcp.NetworkServices.Inputs.TcpRouteRuleActionDestinationArgs
{
ServiceName = @default.Id,
Weight = 1,
},
},
OriginalDestination = false,
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.networkservices.Gateway;
import com.pulumi.gcp.networkservices.GatewayArgs;
import com.pulumi.gcp.networkservices.TcpRoute;
import com.pulumi.gcp.networkservices.TcpRouteArgs;
import com.pulumi.gcp.networkservices.inputs.TcpRouteRuleArgs;
import com.pulumi.gcp.networkservices.inputs.TcpRouteRuleActionArgs;
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 defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
.name("backend-service-health-check")
.requestPath("/")
.checkIntervalSec(1)
.timeoutSec(1)
.build());
var default_ = new BackendService("default", BackendServiceArgs.builder()
.name("my-backend-service")
.healthChecks(defaultHttpHealthCheck.id())
.build());
var defaultGateway = new Gateway("defaultGateway", GatewayArgs.builder()
.name("my-tcp-route")
.labels(Map.of("foo", "bar"))
.description("my description")
.scope("my-scope")
.type("OPEN_MESH")
.ports(443)
.build());
var defaultTcpRoute = new TcpRoute("defaultTcpRoute", TcpRouteArgs.builder()
.name("my-tcp-route")
.labels(Map.of("foo", "bar"))
.description("my description")
.gateways(defaultGateway.id())
.rules(TcpRouteRuleArgs.builder()
.matches(TcpRouteRuleMatchArgs.builder()
.address("10.0.0.1/32")
.port("8081")
.build())
.action(TcpRouteRuleActionArgs.builder()
.destinations(TcpRouteRuleActionDestinationArgs.builder()
.serviceName(default_.id())
.weight(1)
.build())
.originalDestination(false)
.build())
.build())
.build());
}
}
resources:
default:
type: gcp:compute:BackendService
properties:
name: my-backend-service
healthChecks: ${defaultHttpHealthCheck.id}
defaultHttpHealthCheck:
type: gcp:compute:HttpHealthCheck
name: default
properties:
name: backend-service-health-check
requestPath: /
checkIntervalSec: 1
timeoutSec: 1
defaultGateway:
type: gcp:networkservices:Gateway
name: default
properties:
name: my-tcp-route
labels:
foo: bar
description: my description
scope: my-scope
type: OPEN_MESH
ports:
- 443
defaultTcpRoute:
type: gcp:networkservices:TcpRoute
name: default
properties:
name: my-tcp-route
labels:
foo: bar
description: my description
gateways:
- ${defaultGateway.id}
rules:
- matches:
- address: 10.0.0.1/32
port: '8081'
action:
destinations:
- serviceName: ${default.id}
weight: 1
originalDestination: false
The gateways property attaches the route to a Gateway resource, applying the routing rules to traffic entering through that gateway. The Gateway defines the ports and protocols it accepts; the TcpRoute defines where matching traffic goes.
Beyond these examples
These snippets focus on specific TcpRoute features: address and port-based routing, connection timeout configuration, and mesh and gateway attachment. They’re intentionally minimal rather than full traffic management solutions.
The examples reference pre-existing infrastructure such as backend services with health checks, and Mesh or Gateway resources for route attachment. They focus on configuring the route rather than provisioning the complete routing infrastructure.
To keep things focused, common routing patterns are omitted, including:
- Multiple destination weighting and load balancing
- Original destination preservation (originalDestination flag)
- Multiple match rules and rule ordering
- Label-based organization and filtering
These omissions are intentional: the goal is to illustrate how each TcpRoute feature is wired, not provide drop-in traffic management modules. See the TcpRoute resource reference for all available configuration options.
Let's configure GCP TCP Routes
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Routing & Rules
RouteRule must be supplied in the rules property.rules with matches (address and port) and action containing destinations with serviceName and weight properties.Attachment & Integration
gateways and meshes properties, though the examples show them used separately for different routing scenarios.projects/*/locations/global/gateways/<gateway_name>, and mesh references must match projects/*/locations/global/meshes/<mesh_name>.Configuration & Immutability
name and project are immutable and cannot be changed after the TcpRoute is created.labels field is non-authoritative and only manages labels present in your configuration. Use effectiveLabels to see all labels present on the resource in GCP, including those set by other clients and services.Using a different cloud?
Explore networking guides for other cloud providers: