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 backends, 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 existing BackendService resources and attach to Mesh or Gateway resources for traffic management. The examples are intentionally small. Combine them with your own backend services, health checks, and mesh or gateway 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 destination port match. The action.destinations property lists backend services to receive traffic, with weight controlling load distribution. Here, all matching traffic goes to a single backend service.
Configure connection timeout behavior
Long-lived TCP connections need explicit timeout configuration to handle 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 the proxy closes it. This example sets a 60-second timeout. The originalDestination flag determines whether the route preserves the original destination IP address; setting it to false means the proxy rewrites the destination to the backend service address.
Attach routes to service mesh configurations
Service mesh deployments use TcpRoute to define how sidecar proxies route TCP traffic between 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 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 this route to a Mesh resource, making it part of the service mesh routing configuration. Sidecar proxies within the mesh use these rules to route TCP connections between services. The Mesh must be of type SIDECAR.
Attach routes to gateway configurations
Gateway deployments use TcpRoute to define how ingress gateways route external TCP traffic.
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 this route to a Gateway resource, making it part of the gateway’s routing configuration. The gateway evaluates incoming TCP connections against the route’s match rules and forwards traffic to the specified backend services.
Beyond these examples
These snippets focus on specific TcpRoute features: address and port matching, connection timeout configuration, and mesh and gateway attachment. They’re intentionally minimal rather than full traffic management configurations.
The examples reference pre-existing infrastructure such as Compute Engine BackendService resources, health checks for backend services, and Mesh or Gateway resources for attachment examples. They focus on configuring the route rather than provisioning the complete traffic management stack.
To keep things focused, common routing patterns are omitted, including:
- Multiple destination backends with weighted routing
- Original destination preservation (originalDestination flag)
- Multiple match rules per route
- 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
Configuration & Routing
RouteRule must be supplied in the rules array.rules with matches specifying address and port, and action containing destinations with serviceName and weight.idleTimeout within the rule’s action property, such as "60s".description field has a maximum length of 1024 characters.Attachment & Integration
gateways to route requests served by a gateway, or meshes to route requests served by a mesh. Both are optional and use different reference patterns.meshes property with references matching projects/*/locations/global/meshes/<mesh_name>.SIDECAR.Resource Management
name and project properties are immutable and cannot be changed after creation without replacing the resource.labels field is non-authoritative and only manages labels present in your configuration. Use effectiveLabels to see all labels on the resource.projects/{{project}}/locations/global/tcpRoutes/{{name}}, {{project}}/{{name}}, or just {{name}}.Using a different cloud?
Explore networking guides for other cloud providers: