The gcp:networkservices/serviceLbPolicies:ServiceLbPolicies resource, part of the Pulumi GCP provider, defines global load balancing and traffic distribution policies that control how traffic flows to backend services. This guide focuses on three capabilities: traffic distribution algorithms, health-based failover configuration, and regional isolation controls.
Policies are attached to BackendService resources via the serviceLbPolicy property. The examples are intentionally small. Combine them with your own backend services and health checks.
Create a minimal load balancing policy
Most deployments start with a basic policy that establishes the foundation for traffic distribution.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.networkservices.ServiceLbPolicies("default", {
name: "my-lb-policy",
location: "global",
});
import pulumi
import pulumi_gcp as gcp
default = gcp.networkservices.ServiceLbPolicies("default",
name="my-lb-policy",
location="global")
package main
import (
"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 {
_, err := networkservices.NewServiceLbPolicies(ctx, "default", &networkservices.ServiceLbPoliciesArgs{
Name: pulumi.String("my-lb-policy"),
Location: pulumi.String("global"),
})
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 @default = new Gcp.NetworkServices.ServiceLbPolicies("default", new()
{
Name = "my-lb-policy",
Location = "global",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkservices.ServiceLbPolicies;
import com.pulumi.gcp.networkservices.ServiceLbPoliciesArgs;
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 default_ = new ServiceLbPolicies("default", ServiceLbPoliciesArgs.builder()
.name("my-lb-policy")
.location("global")
.build());
}
}
resources:
default:
type: gcp:networkservices:ServiceLbPolicies
properties:
name: my-lb-policy
location: global
The name property identifies the policy, and location must be set to “global” for Service Mesh policies. Without additional configuration, the policy uses default behavior (WATERFALL_BY_REGION algorithm) and can be attached to backend services.
Configure traffic distribution and failover behavior
Production deployments need control over how traffic spreads across regions and how the system responds to unhealthy backends.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.networkservices.ServiceLbPolicies("default", {
name: "my-lb-policy",
location: "global",
description: "my description",
loadBalancingAlgorithm: "SPRAY_TO_REGION",
autoCapacityDrain: {
enable: true,
},
failoverConfig: {
failoverHealthThreshold: 70,
},
labels: {
foo: "bar",
},
});
const defaultBackendService = new gcp.compute.BackendService("default", {
name: "my-lb-backend",
description: "my description",
loadBalancingScheme: "INTERNAL_SELF_MANAGED",
protocol: "HTTP",
serviceLbPolicy: pulumi.interpolate`//networkservices.googleapis.com/${_default.id}`,
});
import pulumi
import pulumi_gcp as gcp
default = gcp.networkservices.ServiceLbPolicies("default",
name="my-lb-policy",
location="global",
description="my description",
load_balancing_algorithm="SPRAY_TO_REGION",
auto_capacity_drain={
"enable": True,
},
failover_config={
"failover_health_threshold": 70,
},
labels={
"foo": "bar",
})
default_backend_service = gcp.compute.BackendService("default",
name="my-lb-backend",
description="my description",
load_balancing_scheme="INTERNAL_SELF_MANAGED",
protocol="HTTP",
service_lb_policy=default.id.apply(lambda id: f"//networkservices.googleapis.com/{id}"))
package main
import (
"fmt"
"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 {
_default, err := networkservices.NewServiceLbPolicies(ctx, "default", &networkservices.ServiceLbPoliciesArgs{
Name: pulumi.String("my-lb-policy"),
Location: pulumi.String("global"),
Description: pulumi.String("my description"),
LoadBalancingAlgorithm: pulumi.String("SPRAY_TO_REGION"),
AutoCapacityDrain: &networkservices.ServiceLbPoliciesAutoCapacityDrainArgs{
Enable: pulumi.Bool(true),
},
FailoverConfig: &networkservices.ServiceLbPoliciesFailoverConfigArgs{
FailoverHealthThreshold: pulumi.Int(70),
},
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
})
if err != nil {
return err
}
_, err = compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("my-lb-backend"),
Description: pulumi.String("my description"),
LoadBalancingScheme: pulumi.String("INTERNAL_SELF_MANAGED"),
Protocol: pulumi.String("HTTP"),
ServiceLbPolicy: _default.ID().ApplyT(func(id string) (string, error) {
return fmt.Sprintf("//networkservices.googleapis.com/%v", id), nil
}).(pulumi.StringOutput),
})
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 @default = new Gcp.NetworkServices.ServiceLbPolicies("default", new()
{
Name = "my-lb-policy",
Location = "global",
Description = "my description",
LoadBalancingAlgorithm = "SPRAY_TO_REGION",
AutoCapacityDrain = new Gcp.NetworkServices.Inputs.ServiceLbPoliciesAutoCapacityDrainArgs
{
Enable = true,
},
FailoverConfig = new Gcp.NetworkServices.Inputs.ServiceLbPoliciesFailoverConfigArgs
{
FailoverHealthThreshold = 70,
},
Labels =
{
{ "foo", "bar" },
},
});
var defaultBackendService = new Gcp.Compute.BackendService("default", new()
{
Name = "my-lb-backend",
Description = "my description",
LoadBalancingScheme = "INTERNAL_SELF_MANAGED",
Protocol = "HTTP",
ServiceLbPolicy = @default.Id.Apply(id => $"//networkservices.googleapis.com/{id}"),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkservices.ServiceLbPolicies;
import com.pulumi.gcp.networkservices.ServiceLbPoliciesArgs;
import com.pulumi.gcp.networkservices.inputs.ServiceLbPoliciesAutoCapacityDrainArgs;
import com.pulumi.gcp.networkservices.inputs.ServiceLbPoliciesFailoverConfigArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
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 default_ = new ServiceLbPolicies("default", ServiceLbPoliciesArgs.builder()
.name("my-lb-policy")
.location("global")
.description("my description")
.loadBalancingAlgorithm("SPRAY_TO_REGION")
.autoCapacityDrain(ServiceLbPoliciesAutoCapacityDrainArgs.builder()
.enable(true)
.build())
.failoverConfig(ServiceLbPoliciesFailoverConfigArgs.builder()
.failoverHealthThreshold(70)
.build())
.labels(Map.of("foo", "bar"))
.build());
var defaultBackendService = new BackendService("defaultBackendService", BackendServiceArgs.builder()
.name("my-lb-backend")
.description("my description")
.loadBalancingScheme("INTERNAL_SELF_MANAGED")
.protocol("HTTP")
.serviceLbPolicy(default_.id().applyValue(_id -> String.format("//networkservices.googleapis.com/%s", _id)))
.build());
}
}
resources:
default:
type: gcp:networkservices:ServiceLbPolicies
properties:
name: my-lb-policy
location: global
description: my description
loadBalancingAlgorithm: SPRAY_TO_REGION
autoCapacityDrain:
enable: true
failoverConfig:
failoverHealthThreshold: 70
labels:
foo: bar
defaultBackendService:
type: gcp:compute:BackendService
name: default
properties:
name: my-lb-backend
description: my description
loadBalancingScheme: INTERNAL_SELF_MANAGED
protocol: HTTP
serviceLbPolicy: //networkservices.googleapis.com/${default.id}
The loadBalancingAlgorithm property determines traffic distribution: SPRAY_TO_REGION spreads requests across all healthy regions, while WATERFALL_BY_REGION prefers closer regions first. The autoCapacityDrain block tells the load balancer to automatically stop sending traffic to unhealthy managed instance groups or network endpoint groups. The failoverConfig sets a health threshold (70%) that triggers failover to backup regions. The BackendService resource references the policy using an interpolated ID that includes the full resource path.
Add isolation controls for regional traffic containment
Applications with data residency requirements can use isolation configuration to control cross-region traffic.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.networkservices.ServiceLbPolicies("default", {
name: "my-lb-policy",
location: "global",
description: "my description",
loadBalancingAlgorithm: "SPRAY_TO_REGION",
autoCapacityDrain: {
enable: true,
},
failoverConfig: {
failoverHealthThreshold: 70,
},
isolationConfig: {
isolationGranularity: "REGION",
isolationMode: "NEAREST",
},
labels: {
foo: "bar",
},
});
const defaultBackendService = new gcp.compute.BackendService("default", {
name: "my-lb-backend",
description: "my description",
loadBalancingScheme: "INTERNAL_SELF_MANAGED",
protocol: "HTTP",
serviceLbPolicy: pulumi.interpolate`//networkservices.googleapis.com/${_default.id}`,
});
import pulumi
import pulumi_gcp as gcp
default = gcp.networkservices.ServiceLbPolicies("default",
name="my-lb-policy",
location="global",
description="my description",
load_balancing_algorithm="SPRAY_TO_REGION",
auto_capacity_drain={
"enable": True,
},
failover_config={
"failover_health_threshold": 70,
},
isolation_config={
"isolation_granularity": "REGION",
"isolation_mode": "NEAREST",
},
labels={
"foo": "bar",
})
default_backend_service = gcp.compute.BackendService("default",
name="my-lb-backend",
description="my description",
load_balancing_scheme="INTERNAL_SELF_MANAGED",
protocol="HTTP",
service_lb_policy=default.id.apply(lambda id: f"//networkservices.googleapis.com/{id}"))
package main
import (
"fmt"
"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 {
_default, err := networkservices.NewServiceLbPolicies(ctx, "default", &networkservices.ServiceLbPoliciesArgs{
Name: pulumi.String("my-lb-policy"),
Location: pulumi.String("global"),
Description: pulumi.String("my description"),
LoadBalancingAlgorithm: pulumi.String("SPRAY_TO_REGION"),
AutoCapacityDrain: &networkservices.ServiceLbPoliciesAutoCapacityDrainArgs{
Enable: pulumi.Bool(true),
},
FailoverConfig: &networkservices.ServiceLbPoliciesFailoverConfigArgs{
FailoverHealthThreshold: pulumi.Int(70),
},
IsolationConfig: &networkservices.ServiceLbPoliciesIsolationConfigArgs{
IsolationGranularity: pulumi.String("REGION"),
IsolationMode: pulumi.String("NEAREST"),
},
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
})
if err != nil {
return err
}
_, err = compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("my-lb-backend"),
Description: pulumi.String("my description"),
LoadBalancingScheme: pulumi.String("INTERNAL_SELF_MANAGED"),
Protocol: pulumi.String("HTTP"),
ServiceLbPolicy: _default.ID().ApplyT(func(id string) (string, error) {
return fmt.Sprintf("//networkservices.googleapis.com/%v", id), nil
}).(pulumi.StringOutput),
})
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 @default = new Gcp.NetworkServices.ServiceLbPolicies("default", new()
{
Name = "my-lb-policy",
Location = "global",
Description = "my description",
LoadBalancingAlgorithm = "SPRAY_TO_REGION",
AutoCapacityDrain = new Gcp.NetworkServices.Inputs.ServiceLbPoliciesAutoCapacityDrainArgs
{
Enable = true,
},
FailoverConfig = new Gcp.NetworkServices.Inputs.ServiceLbPoliciesFailoverConfigArgs
{
FailoverHealthThreshold = 70,
},
IsolationConfig = new Gcp.NetworkServices.Inputs.ServiceLbPoliciesIsolationConfigArgs
{
IsolationGranularity = "REGION",
IsolationMode = "NEAREST",
},
Labels =
{
{ "foo", "bar" },
},
});
var defaultBackendService = new Gcp.Compute.BackendService("default", new()
{
Name = "my-lb-backend",
Description = "my description",
LoadBalancingScheme = "INTERNAL_SELF_MANAGED",
Protocol = "HTTP",
ServiceLbPolicy = @default.Id.Apply(id => $"//networkservices.googleapis.com/{id}"),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networkservices.ServiceLbPolicies;
import com.pulumi.gcp.networkservices.ServiceLbPoliciesArgs;
import com.pulumi.gcp.networkservices.inputs.ServiceLbPoliciesAutoCapacityDrainArgs;
import com.pulumi.gcp.networkservices.inputs.ServiceLbPoliciesFailoverConfigArgs;
import com.pulumi.gcp.networkservices.inputs.ServiceLbPoliciesIsolationConfigArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
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 default_ = new ServiceLbPolicies("default", ServiceLbPoliciesArgs.builder()
.name("my-lb-policy")
.location("global")
.description("my description")
.loadBalancingAlgorithm("SPRAY_TO_REGION")
.autoCapacityDrain(ServiceLbPoliciesAutoCapacityDrainArgs.builder()
.enable(true)
.build())
.failoverConfig(ServiceLbPoliciesFailoverConfigArgs.builder()
.failoverHealthThreshold(70)
.build())
.isolationConfig(ServiceLbPoliciesIsolationConfigArgs.builder()
.isolationGranularity("REGION")
.isolationMode("NEAREST")
.build())
.labels(Map.of("foo", "bar"))
.build());
var defaultBackendService = new BackendService("defaultBackendService", BackendServiceArgs.builder()
.name("my-lb-backend")
.description("my description")
.loadBalancingScheme("INTERNAL_SELF_MANAGED")
.protocol("HTTP")
.serviceLbPolicy(default_.id().applyValue(_id -> String.format("//networkservices.googleapis.com/%s", _id)))
.build());
}
}
resources:
default:
type: gcp:networkservices:ServiceLbPolicies
properties:
name: my-lb-policy
location: global
description: my description
loadBalancingAlgorithm: SPRAY_TO_REGION
autoCapacityDrain:
enable: true
failoverConfig:
failoverHealthThreshold: 70
isolationConfig:
isolationGranularity: REGION
isolationMode: NEAREST
labels:
foo: bar
defaultBackendService:
type: gcp:compute:BackendService
name: default
properties:
name: my-lb-backend
description: my description
loadBalancingScheme: INTERNAL_SELF_MANAGED
protocol: HTTP
serviceLbPolicy: //networkservices.googleapis.com/${default.id}
The isolationConfig block adds regional boundaries to traffic distribution. The isolationGranularity property sets whether isolation applies at the REGION level, and isolationMode determines the fallback behavior: NEAREST keeps traffic in the closest healthy region before failing over. This extends the traffic distribution and failover configuration with an additional containment layer.
Beyond these examples
These snippets focus on specific policy-level features: traffic distribution algorithms, health-based failover and capacity draining, and regional isolation controls. They’re intentionally minimal rather than full load balancing configurations.
The examples may reference pre-existing infrastructure such as GCP projects with Network Services API enabled and backend services to attach policies to. They focus on configuring the policy rather than provisioning the complete load balancing stack.
To keep things focused, common policy patterns are omitted, including:
- Policy attachment to multiple backend services
- Custom health check thresholds beyond failoverHealthThreshold
- Integration with service mesh routing rules
- Policy versioning and rollback strategies
These omissions are intentional: the goal is to illustrate how each policy feature is wired, not provide drop-in load balancing modules. See the ServiceLbPolicies resource reference for all available configuration options.
Let's configure GCP Service Load Balancing Policies
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Provider & Setup
global as the location, as shown in all the examples.Configuration & Algorithms
SPRAY_TO_REGION, SPRAY_TO_WORLD, WATERFALL_BY_REGION (default), and WATERFALL_BY_ZONE.failoverConfig provides health-based failover behavior and is not related to Network Load Balancer FailoverPolicy.Integration & Usage
serviceLbPolicy property to the policy’s ID using the format //networkservices.googleapis.com/${policyId}.Resource Management
project property is immutable and cannot be changed after creation.labels field is non-authoritative and only manages labels in your configuration. Use effectiveLabels to see all labels present on the resource, including those set by other clients and services.Using a different cloud?
Explore networking guides for other cloud providers: