Configure GCP Regional Backend Services

The gcp:compute/regionBackendService:RegionBackendService resource, part of the Pulumi GCP provider, defines a regional backend service that routes load balancer traffic to backend instances, instance groups, or network endpoint groups within a single GCP region. This guide focuses on four capabilities: load balancing schemes, session affinity and connection tracking, Cloud CDN caching, and high availability policies.

Backend services reference health checks, instance groups or NEGs, and VPC networks that must exist separately. The examples are intentionally small. Combine them with your own compute resources and network infrastructure.

Route traffic to backends with health checks

Most internal load balancing deployments start by defining a backend service that routes traffic to healthy instances based on health check results.

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

const defaultHealthCheck = new gcp.compute.HealthCheck("default", {
    name: "rbs-health-check",
    checkIntervalSec: 1,
    timeoutSec: 1,
    tcpHealthCheck: {
        port: 80,
    },
});
const _default = new gcp.compute.RegionBackendService("default", {
    name: "region-service",
    region: "us-central1",
    healthChecks: defaultHealthCheck.id,
    connectionDrainingTimeoutSec: 10,
    sessionAffinity: "CLIENT_IP",
});
import pulumi
import pulumi_gcp as gcp

default_health_check = gcp.compute.HealthCheck("default",
    name="rbs-health-check",
    check_interval_sec=1,
    timeout_sec=1,
    tcp_health_check={
        "port": 80,
    })
default = gcp.compute.RegionBackendService("default",
    name="region-service",
    region="us-central1",
    health_checks=default_health_check.id,
    connection_draining_timeout_sec=10,
    session_affinity="CLIENT_IP")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		defaultHealthCheck, err := compute.NewHealthCheck(ctx, "default", &compute.HealthCheckArgs{
			Name:             pulumi.String("rbs-health-check"),
			CheckIntervalSec: pulumi.Int(1),
			TimeoutSec:       pulumi.Int(1),
			TcpHealthCheck: &compute.HealthCheckTcpHealthCheckArgs{
				Port: pulumi.Int(80),
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionBackendService(ctx, "default", &compute.RegionBackendServiceArgs{
			Name:                         pulumi.String("region-service"),
			Region:                       pulumi.String("us-central1"),
			HealthChecks:                 defaultHealthCheck.ID(),
			ConnectionDrainingTimeoutSec: pulumi.Int(10),
			SessionAffinity:              pulumi.String("CLIENT_IP"),
		})
		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 defaultHealthCheck = new Gcp.Compute.HealthCheck("default", new()
    {
        Name = "rbs-health-check",
        CheckIntervalSec = 1,
        TimeoutSec = 1,
        TcpHealthCheck = new Gcp.Compute.Inputs.HealthCheckTcpHealthCheckArgs
        {
            Port = 80,
        },
    });

    var @default = new Gcp.Compute.RegionBackendService("default", new()
    {
        Name = "region-service",
        Region = "us-central1",
        HealthChecks = defaultHealthCheck.Id,
        ConnectionDrainingTimeoutSec = 10,
        SessionAffinity = "CLIENT_IP",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HealthCheck;
import com.pulumi.gcp.compute.HealthCheckArgs;
import com.pulumi.gcp.compute.inputs.HealthCheckTcpHealthCheckArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
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 defaultHealthCheck = new HealthCheck("defaultHealthCheck", HealthCheckArgs.builder()
            .name("rbs-health-check")
            .checkIntervalSec(1)
            .timeoutSec(1)
            .tcpHealthCheck(HealthCheckTcpHealthCheckArgs.builder()
                .port(80)
                .build())
            .build());

        var default_ = new RegionBackendService("default", RegionBackendServiceArgs.builder()
            .name("region-service")
            .region("us-central1")
            .healthChecks(defaultHealthCheck.id())
            .connectionDrainingTimeoutSec(10)
            .sessionAffinity("CLIENT_IP")
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionBackendService
    properties:
      name: region-service
      region: us-central1
      healthChecks: ${defaultHealthCheck.id}
      connectionDrainingTimeoutSec: 10
      sessionAffinity: CLIENT_IP
  defaultHealthCheck:
    type: gcp:compute:HealthCheck
    name: default
    properties:
      name: rbs-health-check
      checkIntervalSec: 1
      timeoutSec: 1
      tcpHealthCheck:
        port: '80'

The healthChecks property references a health check resource that determines backend availability. The connectionDrainingTimeoutSec property controls how long existing connections remain open when a backend becomes unhealthy. The sessionAffinity property set to CLIENT_IP ensures requests from the same client IP route to the same backend.

Configure internal managed load balancing with round robin

Internal managed load balancers distribute HTTP/HTTPS traffic across backends within a region using configurable algorithms.

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

const healthCheck = new gcp.compute.HealthCheck("health_check", {
    name: "rbs-health-check",
    httpHealthCheck: {
        port: 80,
    },
});
const _default = new gcp.compute.RegionBackendService("default", {
    region: "us-central1",
    name: "region-service",
    healthChecks: healthCheck.id,
    protocol: "HTTP",
    loadBalancingScheme: "INTERNAL_MANAGED",
    localityLbPolicy: "ROUND_ROBIN",
});
import pulumi
import pulumi_gcp as gcp

health_check = gcp.compute.HealthCheck("health_check",
    name="rbs-health-check",
    http_health_check={
        "port": 80,
    })
default = gcp.compute.RegionBackendService("default",
    region="us-central1",
    name="region-service",
    health_checks=health_check.id,
    protocol="HTTP",
    load_balancing_scheme="INTERNAL_MANAGED",
    locality_lb_policy="ROUND_ROBIN")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		healthCheck, err := compute.NewHealthCheck(ctx, "health_check", &compute.HealthCheckArgs{
			Name: pulumi.String("rbs-health-check"),
			HttpHealthCheck: &compute.HealthCheckHttpHealthCheckArgs{
				Port: pulumi.Int(80),
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionBackendService(ctx, "default", &compute.RegionBackendServiceArgs{
			Region:              pulumi.String("us-central1"),
			Name:                pulumi.String("region-service"),
			HealthChecks:        healthCheck.ID(),
			Protocol:            pulumi.String("HTTP"),
			LoadBalancingScheme: pulumi.String("INTERNAL_MANAGED"),
			LocalityLbPolicy:    pulumi.String("ROUND_ROBIN"),
		})
		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 healthCheck = new Gcp.Compute.HealthCheck("health_check", new()
    {
        Name = "rbs-health-check",
        HttpHealthCheck = new Gcp.Compute.Inputs.HealthCheckHttpHealthCheckArgs
        {
            Port = 80,
        },
    });

    var @default = new Gcp.Compute.RegionBackendService("default", new()
    {
        Region = "us-central1",
        Name = "region-service",
        HealthChecks = healthCheck.Id,
        Protocol = "HTTP",
        LoadBalancingScheme = "INTERNAL_MANAGED",
        LocalityLbPolicy = "ROUND_ROBIN",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HealthCheck;
import com.pulumi.gcp.compute.HealthCheckArgs;
import com.pulumi.gcp.compute.inputs.HealthCheckHttpHealthCheckArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
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 healthCheck = new HealthCheck("healthCheck", HealthCheckArgs.builder()
            .name("rbs-health-check")
            .httpHealthCheck(HealthCheckHttpHealthCheckArgs.builder()
                .port(80)
                .build())
            .build());

        var default_ = new RegionBackendService("default", RegionBackendServiceArgs.builder()
            .region("us-central1")
            .name("region-service")
            .healthChecks(healthCheck.id())
            .protocol("HTTP")
            .loadBalancingScheme("INTERNAL_MANAGED")
            .localityLbPolicy("ROUND_ROBIN")
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionBackendService
    properties:
      region: us-central1
      name: region-service
      healthChecks: ${healthCheck.id}
      protocol: HTTP
      loadBalancingScheme: INTERNAL_MANAGED
      localityLbPolicy: ROUND_ROBIN
  healthCheck:
    type: gcp:compute:HealthCheck
    name: health_check
    properties:
      name: rbs-health-check
      httpHealthCheck:
        port: 80

The loadBalancingScheme property set to INTERNAL_MANAGED enables Application Load Balancer features for internal traffic. The localityLbPolicy property controls distribution within the region; ROUND_ROBIN cycles through healthy backends evenly. The protocol property determines the backend communication protocol.

Enable consistent hashing with session affinity

Applications requiring sticky sessions can use ring hash load balancing with HTTP cookie-based affinity.

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

const healthCheck = new gcp.compute.HealthCheck("health_check", {
    name: "rbs-health-check",
    httpHealthCheck: {
        port: 80,
    },
});
const _default = new gcp.compute.RegionBackendService("default", {
    region: "us-central1",
    name: "region-service",
    healthChecks: healthCheck.id,
    loadBalancingScheme: "INTERNAL_MANAGED",
    localityLbPolicy: "RING_HASH",
    sessionAffinity: "HTTP_COOKIE",
    protocol: "HTTP",
    circuitBreakers: {
        maxConnections: 10,
    },
    consistentHash: {
        httpCookie: {
            ttl: {
                seconds: 11,
                nanos: 1111,
            },
            name: "mycookie",
        },
    },
    outlierDetection: {
        consecutiveErrors: 2,
    },
});
import pulumi
import pulumi_gcp as gcp

health_check = gcp.compute.HealthCheck("health_check",
    name="rbs-health-check",
    http_health_check={
        "port": 80,
    })
default = gcp.compute.RegionBackendService("default",
    region="us-central1",
    name="region-service",
    health_checks=health_check.id,
    load_balancing_scheme="INTERNAL_MANAGED",
    locality_lb_policy="RING_HASH",
    session_affinity="HTTP_COOKIE",
    protocol="HTTP",
    circuit_breakers={
        "max_connections": 10,
    },
    consistent_hash={
        "http_cookie": {
            "ttl": {
                "seconds": 11,
                "nanos": 1111,
            },
            "name": "mycookie",
        },
    },
    outlier_detection={
        "consecutive_errors": 2,
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		healthCheck, err := compute.NewHealthCheck(ctx, "health_check", &compute.HealthCheckArgs{
			Name: pulumi.String("rbs-health-check"),
			HttpHealthCheck: &compute.HealthCheckHttpHealthCheckArgs{
				Port: pulumi.Int(80),
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionBackendService(ctx, "default", &compute.RegionBackendServiceArgs{
			Region:              pulumi.String("us-central1"),
			Name:                pulumi.String("region-service"),
			HealthChecks:        healthCheck.ID(),
			LoadBalancingScheme: pulumi.String("INTERNAL_MANAGED"),
			LocalityLbPolicy:    pulumi.String("RING_HASH"),
			SessionAffinity:     pulumi.String("HTTP_COOKIE"),
			Protocol:            pulumi.String("HTTP"),
			CircuitBreakers: &compute.RegionBackendServiceCircuitBreakersArgs{
				MaxConnections: pulumi.Int(10),
			},
			ConsistentHash: &compute.RegionBackendServiceConsistentHashArgs{
				HttpCookie: &compute.RegionBackendServiceConsistentHashHttpCookieArgs{
					Ttl: &compute.RegionBackendServiceConsistentHashHttpCookieTtlArgs{
						Seconds: pulumi.Int(11),
						Nanos:   pulumi.Int(1111),
					},
					Name: pulumi.String("mycookie"),
				},
			},
			OutlierDetection: &compute.RegionBackendServiceOutlierDetectionArgs{
				ConsecutiveErrors: pulumi.Int(2),
			},
		})
		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 healthCheck = new Gcp.Compute.HealthCheck("health_check", new()
    {
        Name = "rbs-health-check",
        HttpHealthCheck = new Gcp.Compute.Inputs.HealthCheckHttpHealthCheckArgs
        {
            Port = 80,
        },
    });

    var @default = new Gcp.Compute.RegionBackendService("default", new()
    {
        Region = "us-central1",
        Name = "region-service",
        HealthChecks = healthCheck.Id,
        LoadBalancingScheme = "INTERNAL_MANAGED",
        LocalityLbPolicy = "RING_HASH",
        SessionAffinity = "HTTP_COOKIE",
        Protocol = "HTTP",
        CircuitBreakers = new Gcp.Compute.Inputs.RegionBackendServiceCircuitBreakersArgs
        {
            MaxConnections = 10,
        },
        ConsistentHash = new Gcp.Compute.Inputs.RegionBackendServiceConsistentHashArgs
        {
            HttpCookie = new Gcp.Compute.Inputs.RegionBackendServiceConsistentHashHttpCookieArgs
            {
                Ttl = new Gcp.Compute.Inputs.RegionBackendServiceConsistentHashHttpCookieTtlArgs
                {
                    Seconds = 11,
                    Nanos = 1111,
                },
                Name = "mycookie",
            },
        },
        OutlierDetection = new Gcp.Compute.Inputs.RegionBackendServiceOutlierDetectionArgs
        {
            ConsecutiveErrors = 2,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HealthCheck;
import com.pulumi.gcp.compute.HealthCheckArgs;
import com.pulumi.gcp.compute.inputs.HealthCheckHttpHealthCheckArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceCircuitBreakersArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceConsistentHashArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceConsistentHashHttpCookieArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceConsistentHashHttpCookieTtlArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceOutlierDetectionArgs;
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 healthCheck = new HealthCheck("healthCheck", HealthCheckArgs.builder()
            .name("rbs-health-check")
            .httpHealthCheck(HealthCheckHttpHealthCheckArgs.builder()
                .port(80)
                .build())
            .build());

        var default_ = new RegionBackendService("default", RegionBackendServiceArgs.builder()
            .region("us-central1")
            .name("region-service")
            .healthChecks(healthCheck.id())
            .loadBalancingScheme("INTERNAL_MANAGED")
            .localityLbPolicy("RING_HASH")
            .sessionAffinity("HTTP_COOKIE")
            .protocol("HTTP")
            .circuitBreakers(RegionBackendServiceCircuitBreakersArgs.builder()
                .maxConnections(10)
                .build())
            .consistentHash(RegionBackendServiceConsistentHashArgs.builder()
                .httpCookie(RegionBackendServiceConsistentHashHttpCookieArgs.builder()
                    .ttl(RegionBackendServiceConsistentHashHttpCookieTtlArgs.builder()
                        .seconds(11)
                        .nanos(1111)
                        .build())
                    .name("mycookie")
                    .build())
                .build())
            .outlierDetection(RegionBackendServiceOutlierDetectionArgs.builder()
                .consecutiveErrors(2)
                .build())
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionBackendService
    properties:
      region: us-central1
      name: region-service
      healthChecks: ${healthCheck.id}
      loadBalancingScheme: INTERNAL_MANAGED
      localityLbPolicy: RING_HASH
      sessionAffinity: HTTP_COOKIE
      protocol: HTTP
      circuitBreakers:
        maxConnections: 10
      consistentHash:
        httpCookie:
          ttl:
            seconds: 11
            nanos: 1111
          name: mycookie
      outlierDetection:
        consecutiveErrors: 2
  healthCheck:
    type: gcp:compute:HealthCheck
    name: health_check
    properties:
      name: rbs-health-check
      httpHealthCheck:
        port: 80

The localityLbPolicy set to RING_HASH implements consistent hashing, where adding or removing backends affects only a fraction of requests. The consistentHash block configures cookie-based routing with TTL settings. The circuitBreakers property limits connections to prevent overload, while outlierDetection removes unhealthy backends based on error rates.

Enable Cloud CDN with cache policies

External load balancers can enable Cloud CDN to cache static content at Google’s edge locations.

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

const defaultRegionHealthCheck = new gcp.compute.RegionHealthCheck("default", {
    name: "rbs-health-check",
    region: "us-central1",
    httpHealthCheck: {
        port: 80,
    },
});
const _default = new gcp.compute.RegionBackendService("default", {
    name: "region-service",
    region: "us-central1",
    healthChecks: defaultRegionHealthCheck.id,
    enableCdn: true,
    cdnPolicy: {
        cacheMode: "CACHE_ALL_STATIC",
        defaultTtl: 3600,
        clientTtl: 7200,
        maxTtl: 10800,
        negativeCaching: true,
        signedUrlCacheMaxAgeSec: 7200,
    },
    loadBalancingScheme: "EXTERNAL",
    protocol: "HTTP",
});
import pulumi
import pulumi_gcp as gcp

default_region_health_check = gcp.compute.RegionHealthCheck("default",
    name="rbs-health-check",
    region="us-central1",
    http_health_check={
        "port": 80,
    })
default = gcp.compute.RegionBackendService("default",
    name="region-service",
    region="us-central1",
    health_checks=default_region_health_check.id,
    enable_cdn=True,
    cdn_policy={
        "cache_mode": "CACHE_ALL_STATIC",
        "default_ttl": 3600,
        "client_ttl": 7200,
        "max_ttl": 10800,
        "negative_caching": True,
        "signed_url_cache_max_age_sec": 7200,
    },
    load_balancing_scheme="EXTERNAL",
    protocol="HTTP")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		defaultRegionHealthCheck, err := compute.NewRegionHealthCheck(ctx, "default", &compute.RegionHealthCheckArgs{
			Name:   pulumi.String("rbs-health-check"),
			Region: pulumi.String("us-central1"),
			HttpHealthCheck: &compute.RegionHealthCheckHttpHealthCheckArgs{
				Port: pulumi.Int(80),
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionBackendService(ctx, "default", &compute.RegionBackendServiceArgs{
			Name:         pulumi.String("region-service"),
			Region:       pulumi.String("us-central1"),
			HealthChecks: defaultRegionHealthCheck.ID(),
			EnableCdn:    pulumi.Bool(true),
			CdnPolicy: &compute.RegionBackendServiceCdnPolicyArgs{
				CacheMode:               pulumi.String("CACHE_ALL_STATIC"),
				DefaultTtl:              pulumi.Int(3600),
				ClientTtl:               pulumi.Int(7200),
				MaxTtl:                  pulumi.Int(10800),
				NegativeCaching:         pulumi.Bool(true),
				SignedUrlCacheMaxAgeSec: pulumi.Int(7200),
			},
			LoadBalancingScheme: pulumi.String("EXTERNAL"),
			Protocol:            pulumi.String("HTTP"),
		})
		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 defaultRegionHealthCheck = new Gcp.Compute.RegionHealthCheck("default", new()
    {
        Name = "rbs-health-check",
        Region = "us-central1",
        HttpHealthCheck = new Gcp.Compute.Inputs.RegionHealthCheckHttpHealthCheckArgs
        {
            Port = 80,
        },
    });

    var @default = new Gcp.Compute.RegionBackendService("default", new()
    {
        Name = "region-service",
        Region = "us-central1",
        HealthChecks = defaultRegionHealthCheck.Id,
        EnableCdn = true,
        CdnPolicy = new Gcp.Compute.Inputs.RegionBackendServiceCdnPolicyArgs
        {
            CacheMode = "CACHE_ALL_STATIC",
            DefaultTtl = 3600,
            ClientTtl = 7200,
            MaxTtl = 10800,
            NegativeCaching = true,
            SignedUrlCacheMaxAgeSec = 7200,
        },
        LoadBalancingScheme = "EXTERNAL",
        Protocol = "HTTP",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.RegionHealthCheck;
import com.pulumi.gcp.compute.RegionHealthCheckArgs;
import com.pulumi.gcp.compute.inputs.RegionHealthCheckHttpHealthCheckArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceCdnPolicyArgs;
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 defaultRegionHealthCheck = new RegionHealthCheck("defaultRegionHealthCheck", RegionHealthCheckArgs.builder()
            .name("rbs-health-check")
            .region("us-central1")
            .httpHealthCheck(RegionHealthCheckHttpHealthCheckArgs.builder()
                .port(80)
                .build())
            .build());

        var default_ = new RegionBackendService("default", RegionBackendServiceArgs.builder()
            .name("region-service")
            .region("us-central1")
            .healthChecks(defaultRegionHealthCheck.id())
            .enableCdn(true)
            .cdnPolicy(RegionBackendServiceCdnPolicyArgs.builder()
                .cacheMode("CACHE_ALL_STATIC")
                .defaultTtl(3600)
                .clientTtl(7200)
                .maxTtl(10800)
                .negativeCaching(true)
                .signedUrlCacheMaxAgeSec(7200)
                .build())
            .loadBalancingScheme("EXTERNAL")
            .protocol("HTTP")
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionBackendService
    properties:
      name: region-service
      region: us-central1
      healthChecks: ${defaultRegionHealthCheck.id}
      enableCdn: true
      cdnPolicy:
        cacheMode: CACHE_ALL_STATIC
        defaultTtl: 3600
        clientTtl: 7200
        maxTtl: 10800
        negativeCaching: true
        signedUrlCacheMaxAgeSec: 7200
      loadBalancingScheme: EXTERNAL
      protocol: HTTP
  defaultRegionHealthCheck:
    type: gcp:compute:RegionHealthCheck
    name: default
    properties:
      name: rbs-health-check
      region: us-central1
      httpHealthCheck:
        port: 80

The enableCdn property activates Cloud CDN for this backend service. The cdnPolicy block configures cache behavior: cacheMode determines what content is cached, defaultTtl sets the default cache duration, and negativeCaching controls whether error responses are cached. The loadBalancingScheme must be EXTERNAL for CDN support.

Attach instance groups with utilization-based balancing

Backend services route traffic to instance groups, with balancing modes that control load distribution.

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

const debianImage = gcp.compute.getImage({
    family: "debian-11",
    project: "debian-cloud",
});
const defaultNetwork = new gcp.compute.Network("default", {
    name: "rbs-net",
    autoCreateSubnetworks: false,
    routingMode: "REGIONAL",
});
const defaultSubnetwork = new gcp.compute.Subnetwork("default", {
    name: "rbs-net-default",
    ipCidrRange: "10.1.2.0/24",
    region: "us-central1",
    network: defaultNetwork.id,
});
const instanceTemplate = new gcp.compute.InstanceTemplate("instance_template", {
    name: "template-region-service",
    machineType: "e2-medium",
    networkInterfaces: [{
        network: defaultNetwork.id,
        subnetwork: defaultSubnetwork.id,
    }],
    disks: [{
        sourceImage: debianImage.then(debianImage => debianImage.selfLink),
        autoDelete: true,
        boot: true,
    }],
    tags: [
        "allow-ssh",
        "load-balanced-backend",
    ],
});
const rigm = new gcp.compute.RegionInstanceGroupManager("rigm", {
    region: "us-central1",
    name: "rbs-rigm",
    versions: [{
        instanceTemplate: instanceTemplate.id,
        name: "primary",
    }],
    baseInstanceName: "internal-glb",
    targetSize: 1,
});
const defaultRegionHealthCheck = new gcp.compute.RegionHealthCheck("default", {
    region: "us-central1",
    name: "rbs-health-check",
    httpHealthCheck: {
        portSpecification: "USE_SERVING_PORT",
    },
});
const _default = new gcp.compute.RegionBackendService("default", {
    loadBalancingScheme: "INTERNAL_MANAGED",
    backends: [{
        group: rigm.instanceGroup,
        balancingMode: "UTILIZATION",
        capacityScaler: 1,
    }],
    region: "us-central1",
    name: "region-service",
    protocol: "H2C",
    timeoutSec: 10,
    healthChecks: defaultRegionHealthCheck.id,
});
import pulumi
import pulumi_gcp as gcp

debian_image = gcp.compute.get_image(family="debian-11",
    project="debian-cloud")
default_network = gcp.compute.Network("default",
    name="rbs-net",
    auto_create_subnetworks=False,
    routing_mode="REGIONAL")
default_subnetwork = gcp.compute.Subnetwork("default",
    name="rbs-net-default",
    ip_cidr_range="10.1.2.0/24",
    region="us-central1",
    network=default_network.id)
instance_template = gcp.compute.InstanceTemplate("instance_template",
    name="template-region-service",
    machine_type="e2-medium",
    network_interfaces=[{
        "network": default_network.id,
        "subnetwork": default_subnetwork.id,
    }],
    disks=[{
        "source_image": debian_image.self_link,
        "auto_delete": True,
        "boot": True,
    }],
    tags=[
        "allow-ssh",
        "load-balanced-backend",
    ])
rigm = gcp.compute.RegionInstanceGroupManager("rigm",
    region="us-central1",
    name="rbs-rigm",
    versions=[{
        "instance_template": instance_template.id,
        "name": "primary",
    }],
    base_instance_name="internal-glb",
    target_size=1)
default_region_health_check = gcp.compute.RegionHealthCheck("default",
    region="us-central1",
    name="rbs-health-check",
    http_health_check={
        "port_specification": "USE_SERVING_PORT",
    })
default = gcp.compute.RegionBackendService("default",
    load_balancing_scheme="INTERNAL_MANAGED",
    backends=[{
        "group": rigm.instance_group,
        "balancing_mode": "UTILIZATION",
        "capacity_scaler": 1,
    }],
    region="us-central1",
    name="region-service",
    protocol="H2C",
    timeout_sec=10,
    health_checks=default_region_health_check.id)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		debianImage, err := compute.LookupImage(ctx, &compute.LookupImageArgs{
			Family:  pulumi.StringRef("debian-11"),
			Project: pulumi.StringRef("debian-cloud"),
		}, nil)
		if err != nil {
			return err
		}
		defaultNetwork, err := compute.NewNetwork(ctx, "default", &compute.NetworkArgs{
			Name:                  pulumi.String("rbs-net"),
			AutoCreateSubnetworks: pulumi.Bool(false),
			RoutingMode:           pulumi.String("REGIONAL"),
		})
		if err != nil {
			return err
		}
		defaultSubnetwork, err := compute.NewSubnetwork(ctx, "default", &compute.SubnetworkArgs{
			Name:        pulumi.String("rbs-net-default"),
			IpCidrRange: pulumi.String("10.1.2.0/24"),
			Region:      pulumi.String("us-central1"),
			Network:     defaultNetwork.ID(),
		})
		if err != nil {
			return err
		}
		instanceTemplate, err := compute.NewInstanceTemplate(ctx, "instance_template", &compute.InstanceTemplateArgs{
			Name:        pulumi.String("template-region-service"),
			MachineType: pulumi.String("e2-medium"),
			NetworkInterfaces: compute.InstanceTemplateNetworkInterfaceArray{
				&compute.InstanceTemplateNetworkInterfaceArgs{
					Network:    defaultNetwork.ID(),
					Subnetwork: defaultSubnetwork.ID(),
				},
			},
			Disks: compute.InstanceTemplateDiskArray{
				&compute.InstanceTemplateDiskArgs{
					SourceImage: pulumi.String(debianImage.SelfLink),
					AutoDelete:  pulumi.Bool(true),
					Boot:        pulumi.Bool(true),
				},
			},
			Tags: pulumi.StringArray{
				pulumi.String("allow-ssh"),
				pulumi.String("load-balanced-backend"),
			},
		})
		if err != nil {
			return err
		}
		rigm, err := compute.NewRegionInstanceGroupManager(ctx, "rigm", &compute.RegionInstanceGroupManagerArgs{
			Region: pulumi.String("us-central1"),
			Name:   pulumi.String("rbs-rigm"),
			Versions: compute.RegionInstanceGroupManagerVersionArray{
				&compute.RegionInstanceGroupManagerVersionArgs{
					InstanceTemplate: instanceTemplate.ID(),
					Name:             pulumi.String("primary"),
				},
			},
			BaseInstanceName: pulumi.String("internal-glb"),
			TargetSize:       pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		defaultRegionHealthCheck, err := compute.NewRegionHealthCheck(ctx, "default", &compute.RegionHealthCheckArgs{
			Region: pulumi.String("us-central1"),
			Name:   pulumi.String("rbs-health-check"),
			HttpHealthCheck: &compute.RegionHealthCheckHttpHealthCheckArgs{
				PortSpecification: pulumi.String("USE_SERVING_PORT"),
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionBackendService(ctx, "default", &compute.RegionBackendServiceArgs{
			LoadBalancingScheme: pulumi.String("INTERNAL_MANAGED"),
			Backends: compute.RegionBackendServiceBackendArray{
				&compute.RegionBackendServiceBackendArgs{
					Group:          rigm.InstanceGroup,
					BalancingMode:  pulumi.String("UTILIZATION"),
					CapacityScaler: pulumi.Float64(1),
				},
			},
			Region:       pulumi.String("us-central1"),
			Name:         pulumi.String("region-service"),
			Protocol:     pulumi.String("H2C"),
			TimeoutSec:   pulumi.Int(10),
			HealthChecks: defaultRegionHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var debianImage = Gcp.Compute.GetImage.Invoke(new()
    {
        Family = "debian-11",
        Project = "debian-cloud",
    });

    var defaultNetwork = new Gcp.Compute.Network("default", new()
    {
        Name = "rbs-net",
        AutoCreateSubnetworks = false,
        RoutingMode = "REGIONAL",
    });

    var defaultSubnetwork = new Gcp.Compute.Subnetwork("default", new()
    {
        Name = "rbs-net-default",
        IpCidrRange = "10.1.2.0/24",
        Region = "us-central1",
        Network = defaultNetwork.Id,
    });

    var instanceTemplate = new Gcp.Compute.InstanceTemplate("instance_template", new()
    {
        Name = "template-region-service",
        MachineType = "e2-medium",
        NetworkInterfaces = new[]
        {
            new Gcp.Compute.Inputs.InstanceTemplateNetworkInterfaceArgs
            {
                Network = defaultNetwork.Id,
                Subnetwork = defaultSubnetwork.Id,
            },
        },
        Disks = new[]
        {
            new Gcp.Compute.Inputs.InstanceTemplateDiskArgs
            {
                SourceImage = debianImage.Apply(getImageResult => getImageResult.SelfLink),
                AutoDelete = true,
                Boot = true,
            },
        },
        Tags = new[]
        {
            "allow-ssh",
            "load-balanced-backend",
        },
    });

    var rigm = new Gcp.Compute.RegionInstanceGroupManager("rigm", new()
    {
        Region = "us-central1",
        Name = "rbs-rigm",
        Versions = new[]
        {
            new Gcp.Compute.Inputs.RegionInstanceGroupManagerVersionArgs
            {
                InstanceTemplate = instanceTemplate.Id,
                Name = "primary",
            },
        },
        BaseInstanceName = "internal-glb",
        TargetSize = 1,
    });

    var defaultRegionHealthCheck = new Gcp.Compute.RegionHealthCheck("default", new()
    {
        Region = "us-central1",
        Name = "rbs-health-check",
        HttpHealthCheck = new Gcp.Compute.Inputs.RegionHealthCheckHttpHealthCheckArgs
        {
            PortSpecification = "USE_SERVING_PORT",
        },
    });

    var @default = new Gcp.Compute.RegionBackendService("default", new()
    {
        LoadBalancingScheme = "INTERNAL_MANAGED",
        Backends = new[]
        {
            new Gcp.Compute.Inputs.RegionBackendServiceBackendArgs
            {
                Group = rigm.InstanceGroup,
                BalancingMode = "UTILIZATION",
                CapacityScaler = 1,
            },
        },
        Region = "us-central1",
        Name = "region-service",
        Protocol = "H2C",
        TimeoutSec = 10,
        HealthChecks = defaultRegionHealthCheck.Id,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetImageArgs;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.compute.InstanceTemplate;
import com.pulumi.gcp.compute.InstanceTemplateArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateNetworkInterfaceArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateDiskArgs;
import com.pulumi.gcp.compute.RegionInstanceGroupManager;
import com.pulumi.gcp.compute.RegionInstanceGroupManagerArgs;
import com.pulumi.gcp.compute.inputs.RegionInstanceGroupManagerVersionArgs;
import com.pulumi.gcp.compute.RegionHealthCheck;
import com.pulumi.gcp.compute.RegionHealthCheckArgs;
import com.pulumi.gcp.compute.inputs.RegionHealthCheckHttpHealthCheckArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceBackendArgs;
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) {
        final var debianImage = ComputeFunctions.getImage(GetImageArgs.builder()
            .family("debian-11")
            .project("debian-cloud")
            .build());

        var defaultNetwork = new Network("defaultNetwork", NetworkArgs.builder()
            .name("rbs-net")
            .autoCreateSubnetworks(false)
            .routingMode("REGIONAL")
            .build());

        var defaultSubnetwork = new Subnetwork("defaultSubnetwork", SubnetworkArgs.builder()
            .name("rbs-net-default")
            .ipCidrRange("10.1.2.0/24")
            .region("us-central1")
            .network(defaultNetwork.id())
            .build());

        var instanceTemplate = new InstanceTemplate("instanceTemplate", InstanceTemplateArgs.builder()
            .name("template-region-service")
            .machineType("e2-medium")
            .networkInterfaces(InstanceTemplateNetworkInterfaceArgs.builder()
                .network(defaultNetwork.id())
                .subnetwork(defaultSubnetwork.id())
                .build())
            .disks(InstanceTemplateDiskArgs.builder()
                .sourceImage(debianImage.selfLink())
                .autoDelete(true)
                .boot(true)
                .build())
            .tags(            
                "allow-ssh",
                "load-balanced-backend")
            .build());

        var rigm = new RegionInstanceGroupManager("rigm", RegionInstanceGroupManagerArgs.builder()
            .region("us-central1")
            .name("rbs-rigm")
            .versions(RegionInstanceGroupManagerVersionArgs.builder()
                .instanceTemplate(instanceTemplate.id())
                .name("primary")
                .build())
            .baseInstanceName("internal-glb")
            .targetSize(1)
            .build());

        var defaultRegionHealthCheck = new RegionHealthCheck("defaultRegionHealthCheck", RegionHealthCheckArgs.builder()
            .region("us-central1")
            .name("rbs-health-check")
            .httpHealthCheck(RegionHealthCheckHttpHealthCheckArgs.builder()
                .portSpecification("USE_SERVING_PORT")
                .build())
            .build());

        var default_ = new RegionBackendService("default", RegionBackendServiceArgs.builder()
            .loadBalancingScheme("INTERNAL_MANAGED")
            .backends(RegionBackendServiceBackendArgs.builder()
                .group(rigm.instanceGroup())
                .balancingMode("UTILIZATION")
                .capacityScaler(1.0)
                .build())
            .region("us-central1")
            .name("region-service")
            .protocol("H2C")
            .timeoutSec(10)
            .healthChecks(defaultRegionHealthCheck.id())
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionBackendService
    properties:
      loadBalancingScheme: INTERNAL_MANAGED
      backends:
        - group: ${rigm.instanceGroup}
          balancingMode: UTILIZATION
          capacityScaler: 1
      region: us-central1
      name: region-service
      protocol: H2C
      timeoutSec: 10
      healthChecks: ${defaultRegionHealthCheck.id}
  rigm:
    type: gcp:compute:RegionInstanceGroupManager
    properties:
      region: us-central1
      name: rbs-rigm
      versions:
        - instanceTemplate: ${instanceTemplate.id}
          name: primary
      baseInstanceName: internal-glb
      targetSize: 1
  instanceTemplate:
    type: gcp:compute:InstanceTemplate
    name: instance_template
    properties:
      name: template-region-service
      machineType: e2-medium
      networkInterfaces:
        - network: ${defaultNetwork.id}
          subnetwork: ${defaultSubnetwork.id}
      disks:
        - sourceImage: ${debianImage.selfLink}
          autoDelete: true
          boot: true
      tags:
        - allow-ssh
        - load-balanced-backend
  defaultRegionHealthCheck:
    type: gcp:compute:RegionHealthCheck
    name: default
    properties:
      region: us-central1
      name: rbs-health-check
      httpHealthCheck:
        portSpecification: USE_SERVING_PORT
  defaultNetwork:
    type: gcp:compute:Network
    name: default
    properties:
      name: rbs-net
      autoCreateSubnetworks: false
      routingMode: REGIONAL
  defaultSubnetwork:
    type: gcp:compute:Subnetwork
    name: default
    properties:
      name: rbs-net-default
      ipCidrRange: 10.1.2.0/24
      region: us-central1
      network: ${defaultNetwork.id}
variables:
  debianImage:
    fn::invoke:
      function: gcp:compute:getImage
      arguments:
        family: debian-11
        project: debian-cloud

The backends array defines instance groups that receive traffic. Each backend specifies a balancingMode (UTILIZATION bases distribution on CPU usage) and capacityScaler (multiplier for the backend’s capacity). The protocol property set to H2C enables HTTP/2 cleartext communication with backends.

Configure connection tracking for TCP load balancing

External TCP load balancers can configure connection tracking policies to control session persistence.

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

const healthCheck = new gcp.compute.RegionHealthCheck("health_check", {
    name: "rbs-health-check",
    region: "us-central1",
    tcpHealthCheck: {
        port: 22,
    },
});
const _default = new gcp.compute.RegionBackendService("default", {
    name: "region-service",
    region: "us-central1",
    healthChecks: healthCheck.id,
    connectionDrainingTimeoutSec: 10,
    sessionAffinity: "CLIENT_IP",
    protocol: "TCP",
    loadBalancingScheme: "EXTERNAL",
    connectionTrackingPolicy: {
        trackingMode: "PER_SESSION",
        connectionPersistenceOnUnhealthyBackends: "NEVER_PERSIST",
        idleTimeoutSec: 60,
        enableStrongAffinity: true,
    },
});
import pulumi
import pulumi_gcp as gcp

health_check = gcp.compute.RegionHealthCheck("health_check",
    name="rbs-health-check",
    region="us-central1",
    tcp_health_check={
        "port": 22,
    })
default = gcp.compute.RegionBackendService("default",
    name="region-service",
    region="us-central1",
    health_checks=health_check.id,
    connection_draining_timeout_sec=10,
    session_affinity="CLIENT_IP",
    protocol="TCP",
    load_balancing_scheme="EXTERNAL",
    connection_tracking_policy={
        "tracking_mode": "PER_SESSION",
        "connection_persistence_on_unhealthy_backends": "NEVER_PERSIST",
        "idle_timeout_sec": 60,
        "enable_strong_affinity": True,
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		healthCheck, err := compute.NewRegionHealthCheck(ctx, "health_check", &compute.RegionHealthCheckArgs{
			Name:   pulumi.String("rbs-health-check"),
			Region: pulumi.String("us-central1"),
			TcpHealthCheck: &compute.RegionHealthCheckTcpHealthCheckArgs{
				Port: pulumi.Int(22),
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionBackendService(ctx, "default", &compute.RegionBackendServiceArgs{
			Name:                         pulumi.String("region-service"),
			Region:                       pulumi.String("us-central1"),
			HealthChecks:                 healthCheck.ID(),
			ConnectionDrainingTimeoutSec: pulumi.Int(10),
			SessionAffinity:              pulumi.String("CLIENT_IP"),
			Protocol:                     pulumi.String("TCP"),
			LoadBalancingScheme:          pulumi.String("EXTERNAL"),
			ConnectionTrackingPolicy: &compute.RegionBackendServiceConnectionTrackingPolicyArgs{
				TrackingMode:                             pulumi.String("PER_SESSION"),
				ConnectionPersistenceOnUnhealthyBackends: pulumi.String("NEVER_PERSIST"),
				IdleTimeoutSec:                           pulumi.Int(60),
				EnableStrongAffinity:                     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 healthCheck = new Gcp.Compute.RegionHealthCheck("health_check", new()
    {
        Name = "rbs-health-check",
        Region = "us-central1",
        TcpHealthCheck = new Gcp.Compute.Inputs.RegionHealthCheckTcpHealthCheckArgs
        {
            Port = 22,
        },
    });

    var @default = new Gcp.Compute.RegionBackendService("default", new()
    {
        Name = "region-service",
        Region = "us-central1",
        HealthChecks = healthCheck.Id,
        ConnectionDrainingTimeoutSec = 10,
        SessionAffinity = "CLIENT_IP",
        Protocol = "TCP",
        LoadBalancingScheme = "EXTERNAL",
        ConnectionTrackingPolicy = new Gcp.Compute.Inputs.RegionBackendServiceConnectionTrackingPolicyArgs
        {
            TrackingMode = "PER_SESSION",
            ConnectionPersistenceOnUnhealthyBackends = "NEVER_PERSIST",
            IdleTimeoutSec = 60,
            EnableStrongAffinity = true,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.RegionHealthCheck;
import com.pulumi.gcp.compute.RegionHealthCheckArgs;
import com.pulumi.gcp.compute.inputs.RegionHealthCheckTcpHealthCheckArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceConnectionTrackingPolicyArgs;
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 healthCheck = new RegionHealthCheck("healthCheck", RegionHealthCheckArgs.builder()
            .name("rbs-health-check")
            .region("us-central1")
            .tcpHealthCheck(RegionHealthCheckTcpHealthCheckArgs.builder()
                .port(22)
                .build())
            .build());

        var default_ = new RegionBackendService("default", RegionBackendServiceArgs.builder()
            .name("region-service")
            .region("us-central1")
            .healthChecks(healthCheck.id())
            .connectionDrainingTimeoutSec(10)
            .sessionAffinity("CLIENT_IP")
            .protocol("TCP")
            .loadBalancingScheme("EXTERNAL")
            .connectionTrackingPolicy(RegionBackendServiceConnectionTrackingPolicyArgs.builder()
                .trackingMode("PER_SESSION")
                .connectionPersistenceOnUnhealthyBackends("NEVER_PERSIST")
                .idleTimeoutSec(60)
                .enableStrongAffinity(true)
                .build())
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionBackendService
    properties:
      name: region-service
      region: us-central1
      healthChecks: ${healthCheck.id}
      connectionDrainingTimeoutSec: 10
      sessionAffinity: CLIENT_IP
      protocol: TCP
      loadBalancingScheme: EXTERNAL
      connectionTrackingPolicy:
        trackingMode: PER_SESSION
        connectionPersistenceOnUnhealthyBackends: NEVER_PERSIST
        idleTimeoutSec: 60
        enableStrongAffinity: true
  healthCheck:
    type: gcp:compute:RegionHealthCheck
    name: health_check
    properties:
      name: rbs-health-check
      region: us-central1
      tcpHealthCheck:
        port: 22

The connectionTrackingPolicy block controls TCP session behavior. The trackingMode set to PER_SESSION maintains state for each connection. The idleTimeoutSec property determines when idle connections are closed. The enableStrongAffinity property ensures connections from the same client always route to the same backend.

Enable high availability with fast IP move

External passthrough load balancers can configure HA policies for automatic failover.

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

const _default = new gcp.compute.Network("default", {name: "rbs-net"});
const defaultRegionBackendService = new gcp.compute.RegionBackendService("default", {
    region: "us-central1",
    name: "region-service",
    protocol: "UDP",
    loadBalancingScheme: "EXTERNAL",
    network: _default.id,
    haPolicy: {
        fastIpMove: "GARP_RA",
    },
    connectionDrainingTimeoutSec: 0,
});
import pulumi
import pulumi_gcp as gcp

default = gcp.compute.Network("default", name="rbs-net")
default_region_backend_service = gcp.compute.RegionBackendService("default",
    region="us-central1",
    name="region-service",
    protocol="UDP",
    load_balancing_scheme="EXTERNAL",
    network=default.id,
    ha_policy={
        "fast_ip_move": "GARP_RA",
    },
    connection_draining_timeout_sec=0)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := compute.NewNetwork(ctx, "default", &compute.NetworkArgs{
			Name: pulumi.String("rbs-net"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionBackendService(ctx, "default", &compute.RegionBackendServiceArgs{
			Region:              pulumi.String("us-central1"),
			Name:                pulumi.String("region-service"),
			Protocol:            pulumi.String("UDP"),
			LoadBalancingScheme: pulumi.String("EXTERNAL"),
			Network:             _default.ID(),
			HaPolicy: &compute.RegionBackendServiceHaPolicyArgs{
				FastIpMove: pulumi.String("GARP_RA"),
			},
			ConnectionDrainingTimeoutSec: pulumi.Int(0),
		})
		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.Compute.Network("default", new()
    {
        Name = "rbs-net",
    });

    var defaultRegionBackendService = new Gcp.Compute.RegionBackendService("default", new()
    {
        Region = "us-central1",
        Name = "region-service",
        Protocol = "UDP",
        LoadBalancingScheme = "EXTERNAL",
        Network = @default.Id,
        HaPolicy = new Gcp.Compute.Inputs.RegionBackendServiceHaPolicyArgs
        {
            FastIpMove = "GARP_RA",
        },
        ConnectionDrainingTimeoutSec = 0,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceHaPolicyArgs;
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 Network("default", NetworkArgs.builder()
            .name("rbs-net")
            .build());

        var defaultRegionBackendService = new RegionBackendService("defaultRegionBackendService", RegionBackendServiceArgs.builder()
            .region("us-central1")
            .name("region-service")
            .protocol("UDP")
            .loadBalancingScheme("EXTERNAL")
            .network(default_.id())
            .haPolicy(RegionBackendServiceHaPolicyArgs.builder()
                .fastIpMove("GARP_RA")
                .build())
            .connectionDrainingTimeoutSec(0)
            .build());

    }
}
resources:
  default:
    type: gcp:compute:Network
    properties:
      name: rbs-net
  defaultRegionBackendService:
    type: gcp:compute:RegionBackendService
    name: default
    properties:
      region: us-central1
      name: region-service
      protocol: UDP
      loadBalancingScheme: EXTERNAL
      network: ${default.id}
      haPolicy:
        fastIpMove: GARP_RA
      connectionDrainingTimeoutSec: 0

The haPolicy block enables high availability features. The fastIpMove property set to GARP_RA uses Gratuitous ARP and Router Advertisement to quickly move IP addresses during failover. The network property specifies the VPC network for HA configuration. The protocol must be UDP or TCP for passthrough load balancing.

Beyond these examples

These snippets focus on specific backend service features: load balancing schemes and locality policies, session affinity and connection tracking, Cloud CDN and cache configuration, and high availability and failover policies. They’re intentionally minimal rather than full load balancing deployments.

The examples reference pre-existing infrastructure such as health check resources, instance groups or network endpoint groups, and VPC networks and subnets. They focus on configuring the backend service rather than provisioning the complete load balancing stack.

To keep things focused, common backend service patterns are omitted, including:

  • Backend configuration (instance groups, NEGs, capacity)
  • IAP (Identity-Aware Proxy) authentication
  • Custom metrics for weighted load balancing
  • Dynamic forwarding and forward proxy modes
  • TLS settings and backend authentication
  • Circuit breakers and outlier detection tuning

These omissions are intentional: the goal is to illustrate how each backend service feature is wired, not provide drop-in load balancing modules. See the Region Backend Service resource reference for all available configuration options.

Let's configure GCP Regional Backend Services

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Common Errors & Pitfalls
Why am I getting resourceInUseByAnotherResource when recreating my backend service?
Recreating a backend service that references dependent resources like instance groups causes this error when decreasing the number of dependent resources. Use lifecycle.create_before_destroy on the dependent resources to avoid this error.
When do I need to specify healthChecks?
A health check must be specified unless the backend service uses an internet or serverless NEG as a backend. Currently at most one health check can be specified.
When should I use portName and when should I omit it?
Use portName when loadBalancingScheme is EXTERNAL, EXTERNAL_MANAGED, INTERNAL_MANAGED, or INTERNAL_SELF_MANAGED and backends are instance groups. Omit it when loadBalancingScheme is INTERNAL (Internal TCP/UDP Load Balancing). The API defaults to “http” if not specified.
Can I use session affinity with UDP protocol?
No, session affinity is not applicable if the protocol is UDP.
Load Balancing & Traffic Management
What load balancing schemes are available?
Five schemes are available: EXTERNAL, EXTERNAL_MANAGED, INTERNAL (default), INTERNAL_MANAGED, and INTERNAL_SELF_MANAGED. The scheme is immutable after creation and determines which features are available.
What locality load balancing policies are available?
Options include ROUND_ROBIN, LEAST_REQUEST, RING_HASH, RANDOM, ORIGINAL_DESTINATION, MAGLEV, WEIGHTED_MAGLEV, and WEIGHTED_ROUND_ROBIN. Applicability depends on loadBalancingScheme and protocol. For External Network Load Balancing, only MAGLEV and WEIGHTED_MAGLEV are supported (default: MAGLEV).
What happens if I set sessionAffinity but use an incompatible localityLbPolicy?
If sessionAffinity is not NONE and localityLbPolicy is not set to MAGLEV, WEIGHTED_MAGLEV, or RING_HASH, session affinity settings will not take effect.
What protocols are supported?
Supported protocols are HTTP (default), HTTPS, HTTP2, H2C, TCP, SSL, UDP, GRPC, and UNSPECIFIED. The protocol determines which features are available.
Advanced Features
How do I enable Cloud CDN?
Set enableCdn to true and configure cdnPolicy with cache settings like cacheMode, defaultTtl, clientTtl, and maxTtl. Requires loadBalancingScheme set to EXTERNAL and protocol set to HTTP.
How do I configure Identity-Aware Proxy?
Configure the iap block with enabled: true, oauth2ClientId, and oauth2ClientSecret. If OAuth client credentials aren’t provided, a Google-managed OAuth client is used.
How do I set up consistent hashing for session affinity?
Set localityLbPolicy to RING_HASH, sessionAffinity to HTTP_COOKIE, and configure consistentHash with httpCookie settings including ttl and name.
How do I configure connection tracking for Layer 4 load balancing?
Configure connectionTrackingPolicy with trackingMode, connectionPersistenceOnUnhealthyBackends, idleTimeoutSec, and enableStrongAffinity. This is available only for Layer 4 Internal Load Balancing and Network Load Balancing.
How do I configure high availability policy?
Configure haPolicy with fastIpMove set to GARP_RA. For manual leader selection, specify leader with backendGroup and networkEndpoint. Available for External and Internal Passthrough Network Load Balancers with GCE_VM_IP NEGs.
How do I configure backend TLS authentication?
Configure tlsSettings with sni, subjectAltNames (using dnsName or uniformResourceIdentifier), and authenticationConfig. This is only available when the backend protocol is SSL, HTTPS, or HTTP2.
Configuration Limits & Immutability
What are the timeout limits?
The default timeout is 30 seconds. The full range allowed is 1 through 2,147,483,647 seconds. The timeout meaning varies depending on the load balancer type.
Which fields can't I change after creation?
The following fields are immutable: name, loadBalancingScheme, network, project, and params. Changes to these fields force recreation of the resource.

Using a different cloud?

Explore networking guides for other cloud providers: