Configure GCP Regional Backend Services

The gcp:compute/regionBackendService:RegionBackendService resource, part of the Pulumi GCP provider, defines a regionally-scoped backend service that routes load balancer traffic to instance groups or network endpoint groups. This guide focuses on five capabilities: health checks and session affinity, CDN caching policies, consistent hashing and circuit breakers, connection tracking for TCP/UDP, and TLS authentication for HTTPS backends.

Backend services reference health checks, instance groups or NEGs, and optionally VPC networks, authentication configs, and security policies. The examples are intentionally small. Combine them with your own compute resources and networking infrastructure.

Create an internal backend service with health checks

Most internal load balancing deployments route traffic to instance groups or network endpoint groups, using health checks to determine which backends can receive traffic.

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 points to a health check resource that monitors backend availability. The sessionAffinity property controls whether requests from the same client route to the same backend; CLIENT_IP uses the client’s IP address for affinity. The connectionDrainingTimeoutSec property sets how long backends continue serving existing connections after being marked unhealthy or removed.

Enable Cloud CDN with cache control policies

Applications serving static content or cacheable API responses can reduce origin load and improve response times by enabling Cloud CDN.

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

When enableCdn is true, the cdnPolicy block controls caching behavior. The cacheMode determines what gets cached; CACHE_ALL_STATIC caches static content automatically. The defaultTtl, clientTtl, and maxTtl properties control how long content stays cached at different layers. The negativeCaching property enables caching of 404 and other error responses. Cloud CDN requires loadBalancingScheme set to EXTERNAL and protocol set to HTTP or HTTPS.

Configure consistent hashing with circuit breakers

Services that need session affinity based on HTTP cookies or headers can use consistent hashing to route requests to the same backend.

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 enables consistent hashing, which routes requests to backends based on a hash of request properties. The consistentHash block defines what to hash; here, an HTTP cookie named “mycookie” with a TTL. The circuitBreakers block limits connections to protect backends from overload. The outlierDetection block removes unhealthy backends after consecutive errors. This configuration requires loadBalancingScheme set to INTERNAL_MANAGED.

Control backend capacity with balancing modes

Backend services can distribute traffic based on different metrics like utilization, rate, or connection count.

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 which instance groups or NEGs receive traffic. Each backend specifies a balancingMode that controls how traffic is distributed; UTILIZATION distributes based on CPU or custom metrics. The capacityScaler multiplies the backend’s capacity, allowing you to gradually shift traffic (e.g., 0.5 sends half the normal traffic). The protocol property determines how the backend service communicates with backends; H2C is HTTP/2 over cleartext.

Configure connection tracking for TCP load balancing

TCP and UDP load balancers can control connection persistence and idle timeout behavior through connection tracking policies.

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 how connections are tracked and maintained. The trackingMode set to PER_SESSION tracks each connection individually. The connectionPersistenceOnUnhealthyBackends property determines whether connections persist when backends become unhealthy; NEVER_PERSIST closes connections immediately. The idleTimeoutSec property sets how long idle connections remain open. The enableStrongAffinity property ensures connections from the same client always route to the same backend. This configuration requires protocol set to TCP and loadBalancingScheme set to EXTERNAL.

Enable backend authentication with TLS settings

Services that communicate with backends over HTTPS can configure TLS settings to verify backend identity.

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

const defaultRegionHealthCheck = new gcp.compute.RegionHealthCheck("default", {
    name: "health-check",
    region: "europe-north1",
    httpHealthCheck: {
        port: 80,
    },
});
const defaultBackendAuthenticationConfig = new gcp.networksecurity.BackendAuthenticationConfig("default", {
    name: "authentication",
    location: "europe-north1",
    wellKnownRoots: "PUBLIC_ROOTS",
});
const _default = new gcp.compute.RegionBackendService("default", {
    region: "europe-north1",
    name: "region-service",
    healthChecks: defaultRegionHealthCheck.id,
    loadBalancingScheme: "EXTERNAL_MANAGED",
    protocol: "HTTPS",
    tlsSettings: {
        sni: "example.com",
        subjectAltNames: [
            {
                dnsName: "example.com",
            },
            {
                uniformResourceIdentifier: "https://example.com",
            },
        ],
        authenticationConfig: pulumi.interpolate`//networksecurity.googleapis.com/${defaultBackendAuthenticationConfig.id}`,
    },
});
import pulumi
import pulumi_gcp as gcp

default_region_health_check = gcp.compute.RegionHealthCheck("default",
    name="health-check",
    region="europe-north1",
    http_health_check={
        "port": 80,
    })
default_backend_authentication_config = gcp.networksecurity.BackendAuthenticationConfig("default",
    name="authentication",
    location="europe-north1",
    well_known_roots="PUBLIC_ROOTS")
default = gcp.compute.RegionBackendService("default",
    region="europe-north1",
    name="region-service",
    health_checks=default_region_health_check.id,
    load_balancing_scheme="EXTERNAL_MANAGED",
    protocol="HTTPS",
    tls_settings={
        "sni": "example.com",
        "subject_alt_names": [
            {
                "dns_name": "example.com",
            },
            {
                "uniform_resource_identifier": "https://example.com",
            },
        ],
        "authentication_config": default_backend_authentication_config.id.apply(lambda id: f"//networksecurity.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/networksecurity"
	"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("health-check"),
			Region: pulumi.String("europe-north1"),
			HttpHealthCheck: &compute.RegionHealthCheckHttpHealthCheckArgs{
				Port: pulumi.Int(80),
			},
		})
		if err != nil {
			return err
		}
		defaultBackendAuthenticationConfig, err := networksecurity.NewBackendAuthenticationConfig(ctx, "default", &networksecurity.BackendAuthenticationConfigArgs{
			Name:           pulumi.String("authentication"),
			Location:       pulumi.String("europe-north1"),
			WellKnownRoots: pulumi.String("PUBLIC_ROOTS"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewRegionBackendService(ctx, "default", &compute.RegionBackendServiceArgs{
			Region:              pulumi.String("europe-north1"),
			Name:                pulumi.String("region-service"),
			HealthChecks:        defaultRegionHealthCheck.ID(),
			LoadBalancingScheme: pulumi.String("EXTERNAL_MANAGED"),
			Protocol:            pulumi.String("HTTPS"),
			TlsSettings: &compute.RegionBackendServiceTlsSettingsArgs{
				Sni: pulumi.String("example.com"),
				SubjectAltNames: compute.RegionBackendServiceTlsSettingsSubjectAltNameArray{
					&compute.RegionBackendServiceTlsSettingsSubjectAltNameArgs{
						DnsName: pulumi.String("example.com"),
					},
					&compute.RegionBackendServiceTlsSettingsSubjectAltNameArgs{
						UniformResourceIdentifier: pulumi.String("https://example.com"),
					},
				},
				AuthenticationConfig: defaultBackendAuthenticationConfig.ID().ApplyT(func(id string) (string, error) {
					return fmt.Sprintf("//networksecurity.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 defaultRegionHealthCheck = new Gcp.Compute.RegionHealthCheck("default", new()
    {
        Name = "health-check",
        Region = "europe-north1",
        HttpHealthCheck = new Gcp.Compute.Inputs.RegionHealthCheckHttpHealthCheckArgs
        {
            Port = 80,
        },
    });

    var defaultBackendAuthenticationConfig = new Gcp.NetworkSecurity.BackendAuthenticationConfig("default", new()
    {
        Name = "authentication",
        Location = "europe-north1",
        WellKnownRoots = "PUBLIC_ROOTS",
    });

    var @default = new Gcp.Compute.RegionBackendService("default", new()
    {
        Region = "europe-north1",
        Name = "region-service",
        HealthChecks = defaultRegionHealthCheck.Id,
        LoadBalancingScheme = "EXTERNAL_MANAGED",
        Protocol = "HTTPS",
        TlsSettings = new Gcp.Compute.Inputs.RegionBackendServiceTlsSettingsArgs
        {
            Sni = "example.com",
            SubjectAltNames = new[]
            {
                new Gcp.Compute.Inputs.RegionBackendServiceTlsSettingsSubjectAltNameArgs
                {
                    DnsName = "example.com",
                },
                new Gcp.Compute.Inputs.RegionBackendServiceTlsSettingsSubjectAltNameArgs
                {
                    UniformResourceIdentifier = "https://example.com",
                },
            },
            AuthenticationConfig = defaultBackendAuthenticationConfig.Id.Apply(id => $"//networksecurity.googleapis.com/{id}"),
        },
    });

});
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.networksecurity.BackendAuthenticationConfig;
import com.pulumi.gcp.networksecurity.BackendAuthenticationConfigArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
import com.pulumi.gcp.compute.inputs.RegionBackendServiceTlsSettingsArgs;
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("health-check")
            .region("europe-north1")
            .httpHealthCheck(RegionHealthCheckHttpHealthCheckArgs.builder()
                .port(80)
                .build())
            .build());

        var defaultBackendAuthenticationConfig = new BackendAuthenticationConfig("defaultBackendAuthenticationConfig", BackendAuthenticationConfigArgs.builder()
            .name("authentication")
            .location("europe-north1")
            .wellKnownRoots("PUBLIC_ROOTS")
            .build());

        var default_ = new RegionBackendService("default", RegionBackendServiceArgs.builder()
            .region("europe-north1")
            .name("region-service")
            .healthChecks(defaultRegionHealthCheck.id())
            .loadBalancingScheme("EXTERNAL_MANAGED")
            .protocol("HTTPS")
            .tlsSettings(RegionBackendServiceTlsSettingsArgs.builder()
                .sni("example.com")
                .subjectAltNames(                
                    RegionBackendServiceTlsSettingsSubjectAltNameArgs.builder()
                        .dnsName("example.com")
                        .build(),
                    RegionBackendServiceTlsSettingsSubjectAltNameArgs.builder()
                        .uniformResourceIdentifier("https://example.com")
                        .build())
                .authenticationConfig(defaultBackendAuthenticationConfig.id().applyValue(_id -> String.format("//networksecurity.googleapis.com/%s", _id)))
                .build())
            .build());

    }
}
resources:
  default:
    type: gcp:compute:RegionBackendService
    properties:
      region: europe-north1
      name: region-service
      healthChecks: ${defaultRegionHealthCheck.id}
      loadBalancingScheme: EXTERNAL_MANAGED
      protocol: HTTPS
      tlsSettings:
        sni: example.com
        subjectAltNames:
          - dnsName: example.com
          - uniformResourceIdentifier: https://example.com
        authenticationConfig: //networksecurity.googleapis.com/${defaultBackendAuthenticationConfig.id}
  defaultRegionHealthCheck:
    type: gcp:compute:RegionHealthCheck
    name: default
    properties:
      name: health-check
      region: europe-north1
      httpHealthCheck:
        port: 80
  defaultBackendAuthenticationConfig:
    type: gcp:networksecurity:BackendAuthenticationConfig
    name: default
    properties:
      name: authentication
      location: europe-north1
      wellKnownRoots: PUBLIC_ROOTS

The tlsSettings block configures TLS for backend connections. The sni property sets the Server Name Indication for TLS handshakes. The subjectAltNames array lists expected certificate identities; dnsName and uniformResourceIdentifier entries are validated against the backend’s certificate. The authenticationConfig property references a backend authentication config resource that defines trusted certificate authorities. This configuration requires protocol set to HTTPS and loadBalancingScheme set to EXTERNAL_MANAGED.

Beyond these examples

These snippets focus on specific backend service features: health checks and session affinity, CDN caching and consistent hashing, and connection tracking and TLS authentication. 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, VPC networks and subnets, and backend authentication configs. They focus on configuring the backend service rather than provisioning the compute and networking resources it routes to.

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

  • Backend group configuration (backends array with instance groups or NEGs)
  • IAP (Identity-Aware Proxy) configuration
  • Failover policies for multi-region deployments
  • Custom metrics for weighted load balancing
  • Dynamic forwarding and HA policies
  • Security policies and logging configuration

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

Resource Lifecycle & Dependencies
Why am I getting a resourceInUseByAnotherResource error when recreating my backend service?
Recreating a RegionBackendService that references dependent resources like gcp.compute.InstanceGroup causes this error when decreasing the number of dependent resources. Use lifecycle.create_before_destroy on the dependent resources to avoid this error.
What properties are immutable after creation?
The name, loadBalancingScheme, network, and params properties cannot be changed after creation. Modifying these properties forces resource recreation.
Load Balancing Configuration
What are the load balancing scheme options and default?
The default is INTERNAL. Available options are EXTERNAL, EXTERNAL_MANAGED, INTERNAL, and INTERNAL_MANAGED. The scheme determines the type of load balancing and affects which other properties are applicable.
What protocols are supported?
Supported protocols are HTTP, HTTPS, HTTP2, H2C, TCP, SSL, UDP, GRPC, and UNSPECIFIED. The default is HTTP. Protocol choice affects which features like session affinity are available.
What's the difference between locality load balancing policies like RING_HASH and MAGLEV?
RING_HASH implements consistent hashing where adding/removing hosts affects only 1/N requests. MAGLEV is a drop-in replacement with faster table lookup and host selection but less stability. WEIGHTED_MAGLEV adds per-instance weighting via health check headers. ROUND_ROBIN and LEAST_REQUEST are simpler policies. Policy applicability depends on loadBalancingScheme and protocol.
Health Checks & Backends
When do I need to specify a health check?
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 via the healthChecks property.
When is the portName property required?
portName is required when loadBalancingScheme is EXTERNAL, EXTERNAL_MANAGED, INTERNAL_MANAGED, or INTERNAL_SELF_MANAGED and backends are instance groups. It must be omitted when loadBalancingScheme is INTERNAL. The API sets a default of “http” if not given.
Session Affinity & Persistence
Can I use session affinity with UDP protocol?
No, session affinity is not applicable if the protocol is UDP. Use a different protocol like TCP, HTTP, or HTTPS if session affinity is needed.
How do I configure stateful session affinity with cookies?
Set sessionAffinity to STRONG_COOKIE_AFFINITY and configure strongSessionAffinityCookie with ttl and name. For hash-based affinity, use HTTP_COOKIE with consistentHash.httpCookie settings.
Advanced Features
How do I enable Cloud CDN caching?
Set enableCdn to true and configure cdnPolicy with settings like cacheMode (e.g., CACHE_ALL_STATIC), defaultTtl, clientTtl, maxTtl, and optionally negativeCaching and signedUrlCacheMaxAgeSec.
When can I use circuit breakers and outlier detection?
Both circuitBreakers and outlierDetection are only applicable when loadBalancingScheme is INTERNAL_MANAGED and protocol is HTTP, HTTPS, HTTP2, or H2C.
What are the restrictions when using haPolicy?
haPolicy cannot be specified with sessionAffinity, connectionTrackingPolicy, failoverPolicy, or healthChecks. It’s only for External and Internal Passthrough Network Load Balancers with GCE_VM_IP NEGs, and customers must manage backend health and leader election.
How do I use custom metrics for weighted load balancing?
Set localityLbPolicy to WEIGHTED_ROUND_ROBIN, define customMetrics at the service level, and configure backends with balancingMode set to CUSTOM_METRICS and backend-specific customMetrics with metric names and optional maxUtilization.
Timeouts & Connection Management
What are the timeout limits for backend services?
The default timeout is 30 seconds. The full range allowed is 1 to 2,147,483,647 seconds. The timeout meaning varies by load balancer type.
How do I configure connection draining?
Set connectionDrainingTimeoutSec to specify how long instances will drain connections (not accept new connections but finish existing work) before being removed.

Using a different cloud?

Explore networking guides for other cloud providers: