The gcp:compute/globalForwardingRule:GlobalForwardingRule resource, part of the Pulumi GCP provider, defines the entry point for global load balancers: the IP address, port, and target that receives incoming traffic. This guide focuses on three capabilities: HTTP load balancing with target proxies, internal self-managed routing for service mesh, and Private Service Connect for Google APIs.
Forwarding rules reference target proxies, URL maps, backend services, and for Private Service Connect, reserved GlobalAddress resources and VPC networks. The examples are intentionally small. Combine them with your own backend infrastructure and routing configuration.
Route HTTP traffic to a target proxy
Most HTTP load balancers start by creating a forwarding rule that accepts traffic on port 80 and directs it to a target proxy.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const defaultHttpHealthCheck = new gcp.compute.HttpHealthCheck("default", {
name: "check-backend",
requestPath: "/",
checkIntervalSec: 1,
timeoutSec: 1,
});
const defaultBackendService = new gcp.compute.BackendService("default", {
name: "backend",
portName: "http",
protocol: "HTTP",
timeoutSec: 10,
healthChecks: defaultHttpHealthCheck.id,
});
const defaultURLMap = new gcp.compute.URLMap("default", {
name: "url-map-target-proxy",
description: "a description",
defaultService: defaultBackendService.id,
hostRules: [{
hosts: ["mysite.com"],
pathMatcher: "allpaths",
}],
pathMatchers: [{
name: "allpaths",
defaultService: defaultBackendService.id,
pathRules: [{
paths: ["/*"],
service: defaultBackendService.id,
}],
}],
});
const defaultTargetHttpProxy = new gcp.compute.TargetHttpProxy("default", {
name: "target-proxy",
description: "a description",
urlMap: defaultURLMap.id,
});
const _default = new gcp.compute.GlobalForwardingRule("default", {
name: "global-rule",
target: defaultTargetHttpProxy.id,
portRange: "80",
});
import pulumi
import pulumi_gcp as gcp
default_http_health_check = gcp.compute.HttpHealthCheck("default",
name="check-backend",
request_path="/",
check_interval_sec=1,
timeout_sec=1)
default_backend_service = gcp.compute.BackendService("default",
name="backend",
port_name="http",
protocol="HTTP",
timeout_sec=10,
health_checks=default_http_health_check.id)
default_url_map = gcp.compute.URLMap("default",
name="url-map-target-proxy",
description="a description",
default_service=default_backend_service.id,
host_rules=[{
"hosts": ["mysite.com"],
"path_matcher": "allpaths",
}],
path_matchers=[{
"name": "allpaths",
"default_service": default_backend_service.id,
"path_rules": [{
"paths": ["/*"],
"service": default_backend_service.id,
}],
}])
default_target_http_proxy = gcp.compute.TargetHttpProxy("default",
name="target-proxy",
description="a description",
url_map=default_url_map.id)
default = gcp.compute.GlobalForwardingRule("default",
name="global-rule",
target=default_target_http_proxy.id,
port_range="80")
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 {
defaultHttpHealthCheck, err := compute.NewHttpHealthCheck(ctx, "default", &compute.HttpHealthCheckArgs{
Name: pulumi.String("check-backend"),
RequestPath: pulumi.String("/"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
})
if err != nil {
return err
}
defaultBackendService, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("backend"),
PortName: pulumi.String("http"),
Protocol: pulumi.String("HTTP"),
TimeoutSec: pulumi.Int(10),
HealthChecks: defaultHttpHealthCheck.ID(),
})
if err != nil {
return err
}
defaultURLMap, err := compute.NewURLMap(ctx, "default", &compute.URLMapArgs{
Name: pulumi.String("url-map-target-proxy"),
Description: pulumi.String("a description"),
DefaultService: defaultBackendService.ID(),
HostRules: compute.URLMapHostRuleArray{
&compute.URLMapHostRuleArgs{
Hosts: pulumi.StringArray{
pulumi.String("mysite.com"),
},
PathMatcher: pulumi.String("allpaths"),
},
},
PathMatchers: compute.URLMapPathMatcherArray{
&compute.URLMapPathMatcherArgs{
Name: pulumi.String("allpaths"),
DefaultService: defaultBackendService.ID(),
PathRules: compute.URLMapPathMatcherPathRuleArray{
&compute.URLMapPathMatcherPathRuleArgs{
Paths: pulumi.StringArray{
pulumi.String("/*"),
},
Service: defaultBackendService.ID(),
},
},
},
},
})
if err != nil {
return err
}
defaultTargetHttpProxy, err := compute.NewTargetHttpProxy(ctx, "default", &compute.TargetHttpProxyArgs{
Name: pulumi.String("target-proxy"),
Description: pulumi.String("a description"),
UrlMap: defaultURLMap.ID(),
})
if err != nil {
return err
}
_, err = compute.NewGlobalForwardingRule(ctx, "default", &compute.GlobalForwardingRuleArgs{
Name: pulumi.String("global-rule"),
Target: defaultTargetHttpProxy.ID(),
PortRange: pulumi.String("80"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var defaultHttpHealthCheck = new Gcp.Compute.HttpHealthCheck("default", new()
{
Name = "check-backend",
RequestPath = "/",
CheckIntervalSec = 1,
TimeoutSec = 1,
});
var defaultBackendService = new Gcp.Compute.BackendService("default", new()
{
Name = "backend",
PortName = "http",
Protocol = "HTTP",
TimeoutSec = 10,
HealthChecks = defaultHttpHealthCheck.Id,
});
var defaultURLMap = new Gcp.Compute.URLMap("default", new()
{
Name = "url-map-target-proxy",
Description = "a description",
DefaultService = defaultBackendService.Id,
HostRules = new[]
{
new Gcp.Compute.Inputs.URLMapHostRuleArgs
{
Hosts = new[]
{
"mysite.com",
},
PathMatcher = "allpaths",
},
},
PathMatchers = new[]
{
new Gcp.Compute.Inputs.URLMapPathMatcherArgs
{
Name = "allpaths",
DefaultService = defaultBackendService.Id,
PathRules = new[]
{
new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
{
Paths = new[]
{
"/*",
},
Service = defaultBackendService.Id,
},
},
},
},
});
var defaultTargetHttpProxy = new Gcp.Compute.TargetHttpProxy("default", new()
{
Name = "target-proxy",
Description = "a description",
UrlMap = defaultURLMap.Id,
});
var @default = new Gcp.Compute.GlobalForwardingRule("default", new()
{
Name = "global-rule",
Target = defaultTargetHttpProxy.Id,
PortRange = "80",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.HttpHealthCheck;
import com.pulumi.gcp.compute.HttpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
import com.pulumi.gcp.compute.TargetHttpProxy;
import com.pulumi.gcp.compute.TargetHttpProxyArgs;
import com.pulumi.gcp.compute.GlobalForwardingRule;
import com.pulumi.gcp.compute.GlobalForwardingRuleArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var defaultHttpHealthCheck = new HttpHealthCheck("defaultHttpHealthCheck", HttpHealthCheckArgs.builder()
.name("check-backend")
.requestPath("/")
.checkIntervalSec(1)
.timeoutSec(1)
.build());
var defaultBackendService = new BackendService("defaultBackendService", BackendServiceArgs.builder()
.name("backend")
.portName("http")
.protocol("HTTP")
.timeoutSec(10)
.healthChecks(defaultHttpHealthCheck.id())
.build());
var defaultURLMap = new URLMap("defaultURLMap", URLMapArgs.builder()
.name("url-map-target-proxy")
.description("a description")
.defaultService(defaultBackendService.id())
.hostRules(URLMapHostRuleArgs.builder()
.hosts("mysite.com")
.pathMatcher("allpaths")
.build())
.pathMatchers(URLMapPathMatcherArgs.builder()
.name("allpaths")
.defaultService(defaultBackendService.id())
.pathRules(URLMapPathMatcherPathRuleArgs.builder()
.paths("/*")
.service(defaultBackendService.id())
.build())
.build())
.build());
var defaultTargetHttpProxy = new TargetHttpProxy("defaultTargetHttpProxy", TargetHttpProxyArgs.builder()
.name("target-proxy")
.description("a description")
.urlMap(defaultURLMap.id())
.build());
var default_ = new GlobalForwardingRule("default", GlobalForwardingRuleArgs.builder()
.name("global-rule")
.target(defaultTargetHttpProxy.id())
.portRange("80")
.build());
}
}
resources:
default:
type: gcp:compute:GlobalForwardingRule
properties:
name: global-rule
target: ${defaultTargetHttpProxy.id}
portRange: '80'
defaultTargetHttpProxy:
type: gcp:compute:TargetHttpProxy
name: default
properties:
name: target-proxy
description: a description
urlMap: ${defaultURLMap.id}
defaultURLMap:
type: gcp:compute:URLMap
name: default
properties:
name: url-map-target-proxy
description: a description
defaultService: ${defaultBackendService.id}
hostRules:
- hosts:
- mysite.com
pathMatcher: allpaths
pathMatchers:
- name: allpaths
defaultService: ${defaultBackendService.id}
pathRules:
- paths:
- /*
service: ${defaultBackendService.id}
defaultBackendService:
type: gcp:compute:BackendService
name: default
properties:
name: backend
portName: http
protocol: HTTP
timeoutSec: 10
healthChecks: ${defaultHttpHealthCheck.id}
defaultHttpHealthCheck:
type: gcp:compute:HttpHealthCheck
name: default
properties:
name: check-backend
requestPath: /
checkIntervalSec: 1
timeoutSec: 1
The forwarding rule accepts traffic on the specified portRange and forwards it to the target, which must be a TargetHttpProxy or TargetHttpsProxy. The target proxy then consults the URLMap to route requests to backend services. When loadBalancingScheme is omitted, it defaults to EXTERNAL, and GCP assigns an ephemeral IP address.
Configure internal self-managed load balancing
Service mesh deployments need internal load balancing without public IPs, using metadata filters to control routing.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const debianImage = gcp.compute.getImage({
family: "debian-11",
project: "debian-cloud",
});
const instanceTemplate = new gcp.compute.InstanceTemplate("instance_template", {
name: "template-backend",
machineType: "e2-medium",
networkInterfaces: [{
network: "default",
}],
disks: [{
sourceImage: debianImage.then(debianImage => debianImage.selfLink),
autoDelete: true,
boot: true,
}],
});
const igm = new gcp.compute.InstanceGroupManager("igm", {
name: "igm-internal",
versions: [{
instanceTemplate: instanceTemplate.id,
name: "primary",
}],
baseInstanceName: "internal-glb",
zone: "us-central1-f",
targetSize: 1,
});
const defaultHealthCheck = new gcp.compute.HealthCheck("default", {
name: "check-backend",
checkIntervalSec: 1,
timeoutSec: 1,
tcpHealthCheck: {
port: 80,
},
});
const defaultBackendService = new gcp.compute.BackendService("default", {
name: "backend",
portName: "http",
protocol: "HTTP",
timeoutSec: 10,
loadBalancingScheme: "INTERNAL_SELF_MANAGED",
backends: [{
group: igm.instanceGroup,
balancingMode: "RATE",
capacityScaler: 0.4,
maxRatePerInstance: 50,
}],
healthChecks: defaultHealthCheck.id,
});
const defaultURLMap = new gcp.compute.URLMap("default", {
name: "url-map-target-proxy",
description: "a description",
defaultService: defaultBackendService.id,
hostRules: [{
hosts: ["mysite.com"],
pathMatcher: "allpaths",
}],
pathMatchers: [{
name: "allpaths",
defaultService: defaultBackendService.id,
pathRules: [{
paths: ["/*"],
service: defaultBackendService.id,
}],
}],
});
const defaultTargetHttpProxy = new gcp.compute.TargetHttpProxy("default", {
name: "target-proxy",
description: "a description",
urlMap: defaultURLMap.id,
});
const _default = new gcp.compute.GlobalForwardingRule("default", {
name: "global-rule",
target: defaultTargetHttpProxy.id,
portRange: "80",
loadBalancingScheme: "INTERNAL_SELF_MANAGED",
ipAddress: "0.0.0.0",
metadataFilters: [{
filterMatchCriteria: "MATCH_ANY",
filterLabels: [{
name: "PLANET",
value: "MARS",
}],
}],
});
import pulumi
import pulumi_gcp as gcp
debian_image = gcp.compute.get_image(family="debian-11",
project="debian-cloud")
instance_template = gcp.compute.InstanceTemplate("instance_template",
name="template-backend",
machine_type="e2-medium",
network_interfaces=[{
"network": "default",
}],
disks=[{
"source_image": debian_image.self_link,
"auto_delete": True,
"boot": True,
}])
igm = gcp.compute.InstanceGroupManager("igm",
name="igm-internal",
versions=[{
"instance_template": instance_template.id,
"name": "primary",
}],
base_instance_name="internal-glb",
zone="us-central1-f",
target_size=1)
default_health_check = gcp.compute.HealthCheck("default",
name="check-backend",
check_interval_sec=1,
timeout_sec=1,
tcp_health_check={
"port": 80,
})
default_backend_service = gcp.compute.BackendService("default",
name="backend",
port_name="http",
protocol="HTTP",
timeout_sec=10,
load_balancing_scheme="INTERNAL_SELF_MANAGED",
backends=[{
"group": igm.instance_group,
"balancing_mode": "RATE",
"capacity_scaler": 0.4,
"max_rate_per_instance": 50,
}],
health_checks=default_health_check.id)
default_url_map = gcp.compute.URLMap("default",
name="url-map-target-proxy",
description="a description",
default_service=default_backend_service.id,
host_rules=[{
"hosts": ["mysite.com"],
"path_matcher": "allpaths",
}],
path_matchers=[{
"name": "allpaths",
"default_service": default_backend_service.id,
"path_rules": [{
"paths": ["/*"],
"service": default_backend_service.id,
}],
}])
default_target_http_proxy = gcp.compute.TargetHttpProxy("default",
name="target-proxy",
description="a description",
url_map=default_url_map.id)
default = gcp.compute.GlobalForwardingRule("default",
name="global-rule",
target=default_target_http_proxy.id,
port_range="80",
load_balancing_scheme="INTERNAL_SELF_MANAGED",
ip_address="0.0.0.0",
metadata_filters=[{
"filter_match_criteria": "MATCH_ANY",
"filter_labels": [{
"name": "PLANET",
"value": "MARS",
}],
}])
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
}
instanceTemplate, err := compute.NewInstanceTemplate(ctx, "instance_template", &compute.InstanceTemplateArgs{
Name: pulumi.String("template-backend"),
MachineType: pulumi.String("e2-medium"),
NetworkInterfaces: compute.InstanceTemplateNetworkInterfaceArray{
&compute.InstanceTemplateNetworkInterfaceArgs{
Network: pulumi.String("default"),
},
},
Disks: compute.InstanceTemplateDiskArray{
&compute.InstanceTemplateDiskArgs{
SourceImage: pulumi.String(debianImage.SelfLink),
AutoDelete: pulumi.Bool(true),
Boot: pulumi.Bool(true),
},
},
})
if err != nil {
return err
}
igm, err := compute.NewInstanceGroupManager(ctx, "igm", &compute.InstanceGroupManagerArgs{
Name: pulumi.String("igm-internal"),
Versions: compute.InstanceGroupManagerVersionArray{
&compute.InstanceGroupManagerVersionArgs{
InstanceTemplate: instanceTemplate.ID(),
Name: pulumi.String("primary"),
},
},
BaseInstanceName: pulumi.String("internal-glb"),
Zone: pulumi.String("us-central1-f"),
TargetSize: pulumi.Int(1),
})
if err != nil {
return err
}
defaultHealthCheck, err := compute.NewHealthCheck(ctx, "default", &compute.HealthCheckArgs{
Name: pulumi.String("check-backend"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
TcpHealthCheck: &compute.HealthCheckTcpHealthCheckArgs{
Port: pulumi.Int(80),
},
})
if err != nil {
return err
}
defaultBackendService, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("backend"),
PortName: pulumi.String("http"),
Protocol: pulumi.String("HTTP"),
TimeoutSec: pulumi.Int(10),
LoadBalancingScheme: pulumi.String("INTERNAL_SELF_MANAGED"),
Backends: compute.BackendServiceBackendArray{
&compute.BackendServiceBackendArgs{
Group: igm.InstanceGroup,
BalancingMode: pulumi.String("RATE"),
CapacityScaler: pulumi.Float64(0.4),
MaxRatePerInstance: pulumi.Float64(50),
},
},
HealthChecks: defaultHealthCheck.ID(),
})
if err != nil {
return err
}
defaultURLMap, err := compute.NewURLMap(ctx, "default", &compute.URLMapArgs{
Name: pulumi.String("url-map-target-proxy"),
Description: pulumi.String("a description"),
DefaultService: defaultBackendService.ID(),
HostRules: compute.URLMapHostRuleArray{
&compute.URLMapHostRuleArgs{
Hosts: pulumi.StringArray{
pulumi.String("mysite.com"),
},
PathMatcher: pulumi.String("allpaths"),
},
},
PathMatchers: compute.URLMapPathMatcherArray{
&compute.URLMapPathMatcherArgs{
Name: pulumi.String("allpaths"),
DefaultService: defaultBackendService.ID(),
PathRules: compute.URLMapPathMatcherPathRuleArray{
&compute.URLMapPathMatcherPathRuleArgs{
Paths: pulumi.StringArray{
pulumi.String("/*"),
},
Service: defaultBackendService.ID(),
},
},
},
},
})
if err != nil {
return err
}
defaultTargetHttpProxy, err := compute.NewTargetHttpProxy(ctx, "default", &compute.TargetHttpProxyArgs{
Name: pulumi.String("target-proxy"),
Description: pulumi.String("a description"),
UrlMap: defaultURLMap.ID(),
})
if err != nil {
return err
}
_, err = compute.NewGlobalForwardingRule(ctx, "default", &compute.GlobalForwardingRuleArgs{
Name: pulumi.String("global-rule"),
Target: defaultTargetHttpProxy.ID(),
PortRange: pulumi.String("80"),
LoadBalancingScheme: pulumi.String("INTERNAL_SELF_MANAGED"),
IpAddress: pulumi.String("0.0.0.0"),
MetadataFilters: compute.GlobalForwardingRuleMetadataFilterArray{
&compute.GlobalForwardingRuleMetadataFilterArgs{
FilterMatchCriteria: pulumi.String("MATCH_ANY"),
FilterLabels: compute.GlobalForwardingRuleMetadataFilterFilterLabelArray{
&compute.GlobalForwardingRuleMetadataFilterFilterLabelArgs{
Name: pulumi.String("PLANET"),
Value: pulumi.String("MARS"),
},
},
},
},
})
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 instanceTemplate = new Gcp.Compute.InstanceTemplate("instance_template", new()
{
Name = "template-backend",
MachineType = "e2-medium",
NetworkInterfaces = new[]
{
new Gcp.Compute.Inputs.InstanceTemplateNetworkInterfaceArgs
{
Network = "default",
},
},
Disks = new[]
{
new Gcp.Compute.Inputs.InstanceTemplateDiskArgs
{
SourceImage = debianImage.Apply(getImageResult => getImageResult.SelfLink),
AutoDelete = true,
Boot = true,
},
},
});
var igm = new Gcp.Compute.InstanceGroupManager("igm", new()
{
Name = "igm-internal",
Versions = new[]
{
new Gcp.Compute.Inputs.InstanceGroupManagerVersionArgs
{
InstanceTemplate = instanceTemplate.Id,
Name = "primary",
},
},
BaseInstanceName = "internal-glb",
Zone = "us-central1-f",
TargetSize = 1,
});
var defaultHealthCheck = new Gcp.Compute.HealthCheck("default", new()
{
Name = "check-backend",
CheckIntervalSec = 1,
TimeoutSec = 1,
TcpHealthCheck = new Gcp.Compute.Inputs.HealthCheckTcpHealthCheckArgs
{
Port = 80,
},
});
var defaultBackendService = new Gcp.Compute.BackendService("default", new()
{
Name = "backend",
PortName = "http",
Protocol = "HTTP",
TimeoutSec = 10,
LoadBalancingScheme = "INTERNAL_SELF_MANAGED",
Backends = new[]
{
new Gcp.Compute.Inputs.BackendServiceBackendArgs
{
Group = igm.InstanceGroup,
BalancingMode = "RATE",
CapacityScaler = 0.4,
MaxRatePerInstance = 50,
},
},
HealthChecks = defaultHealthCheck.Id,
});
var defaultURLMap = new Gcp.Compute.URLMap("default", new()
{
Name = "url-map-target-proxy",
Description = "a description",
DefaultService = defaultBackendService.Id,
HostRules = new[]
{
new Gcp.Compute.Inputs.URLMapHostRuleArgs
{
Hosts = new[]
{
"mysite.com",
},
PathMatcher = "allpaths",
},
},
PathMatchers = new[]
{
new Gcp.Compute.Inputs.URLMapPathMatcherArgs
{
Name = "allpaths",
DefaultService = defaultBackendService.Id,
PathRules = new[]
{
new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
{
Paths = new[]
{
"/*",
},
Service = defaultBackendService.Id,
},
},
},
},
});
var defaultTargetHttpProxy = new Gcp.Compute.TargetHttpProxy("default", new()
{
Name = "target-proxy",
Description = "a description",
UrlMap = defaultURLMap.Id,
});
var @default = new Gcp.Compute.GlobalForwardingRule("default", new()
{
Name = "global-rule",
Target = defaultTargetHttpProxy.Id,
PortRange = "80",
LoadBalancingScheme = "INTERNAL_SELF_MANAGED",
IpAddress = "0.0.0.0",
MetadataFilters = new[]
{
new Gcp.Compute.Inputs.GlobalForwardingRuleMetadataFilterArgs
{
FilterMatchCriteria = "MATCH_ANY",
FilterLabels = new[]
{
new Gcp.Compute.Inputs.GlobalForwardingRuleMetadataFilterFilterLabelArgs
{
Name = "PLANET",
Value = "MARS",
},
},
},
},
});
});
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.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.InstanceGroupManager;
import com.pulumi.gcp.compute.InstanceGroupManagerArgs;
import com.pulumi.gcp.compute.inputs.InstanceGroupManagerVersionArgs;
import com.pulumi.gcp.compute.HealthCheck;
import com.pulumi.gcp.compute.HealthCheckArgs;
import com.pulumi.gcp.compute.inputs.HealthCheckTcpHealthCheckArgs;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.compute.inputs.BackendServiceBackendArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
import com.pulumi.gcp.compute.TargetHttpProxy;
import com.pulumi.gcp.compute.TargetHttpProxyArgs;
import com.pulumi.gcp.compute.GlobalForwardingRule;
import com.pulumi.gcp.compute.GlobalForwardingRuleArgs;
import com.pulumi.gcp.compute.inputs.GlobalForwardingRuleMetadataFilterArgs;
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 instanceTemplate = new InstanceTemplate("instanceTemplate", InstanceTemplateArgs.builder()
.name("template-backend")
.machineType("e2-medium")
.networkInterfaces(InstanceTemplateNetworkInterfaceArgs.builder()
.network("default")
.build())
.disks(InstanceTemplateDiskArgs.builder()
.sourceImage(debianImage.selfLink())
.autoDelete(true)
.boot(true)
.build())
.build());
var igm = new InstanceGroupManager("igm", InstanceGroupManagerArgs.builder()
.name("igm-internal")
.versions(InstanceGroupManagerVersionArgs.builder()
.instanceTemplate(instanceTemplate.id())
.name("primary")
.build())
.baseInstanceName("internal-glb")
.zone("us-central1-f")
.targetSize(1)
.build());
var defaultHealthCheck = new HealthCheck("defaultHealthCheck", HealthCheckArgs.builder()
.name("check-backend")
.checkIntervalSec(1)
.timeoutSec(1)
.tcpHealthCheck(HealthCheckTcpHealthCheckArgs.builder()
.port(80)
.build())
.build());
var defaultBackendService = new BackendService("defaultBackendService", BackendServiceArgs.builder()
.name("backend")
.portName("http")
.protocol("HTTP")
.timeoutSec(10)
.loadBalancingScheme("INTERNAL_SELF_MANAGED")
.backends(BackendServiceBackendArgs.builder()
.group(igm.instanceGroup())
.balancingMode("RATE")
.capacityScaler(0.4)
.maxRatePerInstance(50.0)
.build())
.healthChecks(defaultHealthCheck.id())
.build());
var defaultURLMap = new URLMap("defaultURLMap", URLMapArgs.builder()
.name("url-map-target-proxy")
.description("a description")
.defaultService(defaultBackendService.id())
.hostRules(URLMapHostRuleArgs.builder()
.hosts("mysite.com")
.pathMatcher("allpaths")
.build())
.pathMatchers(URLMapPathMatcherArgs.builder()
.name("allpaths")
.defaultService(defaultBackendService.id())
.pathRules(URLMapPathMatcherPathRuleArgs.builder()
.paths("/*")
.service(defaultBackendService.id())
.build())
.build())
.build());
var defaultTargetHttpProxy = new TargetHttpProxy("defaultTargetHttpProxy", TargetHttpProxyArgs.builder()
.name("target-proxy")
.description("a description")
.urlMap(defaultURLMap.id())
.build());
var default_ = new GlobalForwardingRule("default", GlobalForwardingRuleArgs.builder()
.name("global-rule")
.target(defaultTargetHttpProxy.id())
.portRange("80")
.loadBalancingScheme("INTERNAL_SELF_MANAGED")
.ipAddress("0.0.0.0")
.metadataFilters(GlobalForwardingRuleMetadataFilterArgs.builder()
.filterMatchCriteria("MATCH_ANY")
.filterLabels(GlobalForwardingRuleMetadataFilterFilterLabelArgs.builder()
.name("PLANET")
.value("MARS")
.build())
.build())
.build());
}
}
resources:
default:
type: gcp:compute:GlobalForwardingRule
properties:
name: global-rule
target: ${defaultTargetHttpProxy.id}
portRange: '80'
loadBalancingScheme: INTERNAL_SELF_MANAGED
ipAddress: 0.0.0.0
metadataFilters:
- filterMatchCriteria: MATCH_ANY
filterLabels:
- name: PLANET
value: MARS
defaultTargetHttpProxy:
type: gcp:compute:TargetHttpProxy
name: default
properties:
name: target-proxy
description: a description
urlMap: ${defaultURLMap.id}
defaultURLMap:
type: gcp:compute:URLMap
name: default
properties:
name: url-map-target-proxy
description: a description
defaultService: ${defaultBackendService.id}
hostRules:
- hosts:
- mysite.com
pathMatcher: allpaths
pathMatchers:
- name: allpaths
defaultService: ${defaultBackendService.id}
pathRules:
- paths:
- /*
service: ${defaultBackendService.id}
defaultBackendService:
type: gcp:compute:BackendService
name: default
properties:
name: backend
portName: http
protocol: HTTP
timeoutSec: 10
loadBalancingScheme: INTERNAL_SELF_MANAGED
backends:
- group: ${igm.instanceGroup}
balancingMode: RATE
capacityScaler: 0.4
maxRatePerInstance: 50
healthChecks: ${defaultHealthCheck.id}
igm:
type: gcp:compute:InstanceGroupManager
properties:
name: igm-internal
versions:
- instanceTemplate: ${instanceTemplate.id}
name: primary
baseInstanceName: internal-glb
zone: us-central1-f
targetSize: 1
instanceTemplate:
type: gcp:compute:InstanceTemplate
name: instance_template
properties:
name: template-backend
machineType: e2-medium
networkInterfaces:
- network: default
disks:
- sourceImage: ${debianImage.selfLink}
autoDelete: true
boot: true
defaultHealthCheck:
type: gcp:compute:HealthCheck
name: default
properties:
name: check-backend
checkIntervalSec: 1
timeoutSec: 1
tcpHealthCheck:
port: '80'
variables:
debianImage:
fn::invoke:
function: gcp:compute:getImage
arguments:
family: debian-11
project: debian-cloud
Setting loadBalancingScheme to INTERNAL_SELF_MANAGED creates a forwarding rule for xDS-based service mesh integration. The ipAddress of 0.0.0.0 is a special value for internal self-managed rules. The metadataFilters property restricts which xDS clients receive routing configuration based on node metadata they present.
Use external managed load balancing with premium tier
Modern Application Load Balancers use EXTERNAL_MANAGED for advanced traffic management features.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const defaultBackendService = new gcp.compute.BackendService("default", {
name: "backend",
portName: "http",
protocol: "HTTP",
timeoutSec: 10,
loadBalancingScheme: "EXTERNAL_MANAGED",
});
const defaultURLMap = new gcp.compute.URLMap("default", {
name: "url-map-target-proxy",
description: "a description",
defaultService: defaultBackendService.id,
hostRules: [{
hosts: ["mysite.com"],
pathMatcher: "allpaths",
}],
pathMatchers: [{
name: "allpaths",
defaultService: defaultBackendService.id,
pathRules: [{
paths: ["/*"],
service: defaultBackendService.id,
}],
}],
});
const defaultTargetHttpProxy = new gcp.compute.TargetHttpProxy("default", {
name: "target-proxy",
description: "a description",
urlMap: defaultURLMap.id,
});
const _default = new gcp.compute.GlobalForwardingRule("default", {
name: "global-rule",
target: defaultTargetHttpProxy.id,
portRange: "80",
loadBalancingScheme: "EXTERNAL_MANAGED",
networkTier: "PREMIUM",
});
import pulumi
import pulumi_gcp as gcp
default_backend_service = gcp.compute.BackendService("default",
name="backend",
port_name="http",
protocol="HTTP",
timeout_sec=10,
load_balancing_scheme="EXTERNAL_MANAGED")
default_url_map = gcp.compute.URLMap("default",
name="url-map-target-proxy",
description="a description",
default_service=default_backend_service.id,
host_rules=[{
"hosts": ["mysite.com"],
"path_matcher": "allpaths",
}],
path_matchers=[{
"name": "allpaths",
"default_service": default_backend_service.id,
"path_rules": [{
"paths": ["/*"],
"service": default_backend_service.id,
}],
}])
default_target_http_proxy = gcp.compute.TargetHttpProxy("default",
name="target-proxy",
description="a description",
url_map=default_url_map.id)
default = gcp.compute.GlobalForwardingRule("default",
name="global-rule",
target=default_target_http_proxy.id,
port_range="80",
load_balancing_scheme="EXTERNAL_MANAGED",
network_tier="PREMIUM")
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 {
defaultBackendService, err := compute.NewBackendService(ctx, "default", &compute.BackendServiceArgs{
Name: pulumi.String("backend"),
PortName: pulumi.String("http"),
Protocol: pulumi.String("HTTP"),
TimeoutSec: pulumi.Int(10),
LoadBalancingScheme: pulumi.String("EXTERNAL_MANAGED"),
})
if err != nil {
return err
}
defaultURLMap, err := compute.NewURLMap(ctx, "default", &compute.URLMapArgs{
Name: pulumi.String("url-map-target-proxy"),
Description: pulumi.String("a description"),
DefaultService: defaultBackendService.ID(),
HostRules: compute.URLMapHostRuleArray{
&compute.URLMapHostRuleArgs{
Hosts: pulumi.StringArray{
pulumi.String("mysite.com"),
},
PathMatcher: pulumi.String("allpaths"),
},
},
PathMatchers: compute.URLMapPathMatcherArray{
&compute.URLMapPathMatcherArgs{
Name: pulumi.String("allpaths"),
DefaultService: defaultBackendService.ID(),
PathRules: compute.URLMapPathMatcherPathRuleArray{
&compute.URLMapPathMatcherPathRuleArgs{
Paths: pulumi.StringArray{
pulumi.String("/*"),
},
Service: defaultBackendService.ID(),
},
},
},
},
})
if err != nil {
return err
}
defaultTargetHttpProxy, err := compute.NewTargetHttpProxy(ctx, "default", &compute.TargetHttpProxyArgs{
Name: pulumi.String("target-proxy"),
Description: pulumi.String("a description"),
UrlMap: defaultURLMap.ID(),
})
if err != nil {
return err
}
_, err = compute.NewGlobalForwardingRule(ctx, "default", &compute.GlobalForwardingRuleArgs{
Name: pulumi.String("global-rule"),
Target: defaultTargetHttpProxy.ID(),
PortRange: pulumi.String("80"),
LoadBalancingScheme: pulumi.String("EXTERNAL_MANAGED"),
NetworkTier: pulumi.String("PREMIUM"),
})
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 defaultBackendService = new Gcp.Compute.BackendService("default", new()
{
Name = "backend",
PortName = "http",
Protocol = "HTTP",
TimeoutSec = 10,
LoadBalancingScheme = "EXTERNAL_MANAGED",
});
var defaultURLMap = new Gcp.Compute.URLMap("default", new()
{
Name = "url-map-target-proxy",
Description = "a description",
DefaultService = defaultBackendService.Id,
HostRules = new[]
{
new Gcp.Compute.Inputs.URLMapHostRuleArgs
{
Hosts = new[]
{
"mysite.com",
},
PathMatcher = "allpaths",
},
},
PathMatchers = new[]
{
new Gcp.Compute.Inputs.URLMapPathMatcherArgs
{
Name = "allpaths",
DefaultService = defaultBackendService.Id,
PathRules = new[]
{
new Gcp.Compute.Inputs.URLMapPathMatcherPathRuleArgs
{
Paths = new[]
{
"/*",
},
Service = defaultBackendService.Id,
},
},
},
},
});
var defaultTargetHttpProxy = new Gcp.Compute.TargetHttpProxy("default", new()
{
Name = "target-proxy",
Description = "a description",
UrlMap = defaultURLMap.Id,
});
var @default = new Gcp.Compute.GlobalForwardingRule("default", new()
{
Name = "global-rule",
Target = defaultTargetHttpProxy.Id,
PortRange = "80",
LoadBalancingScheme = "EXTERNAL_MANAGED",
NetworkTier = "PREMIUM",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.BackendService;
import com.pulumi.gcp.compute.BackendServiceArgs;
import com.pulumi.gcp.compute.URLMap;
import com.pulumi.gcp.compute.URLMapArgs;
import com.pulumi.gcp.compute.inputs.URLMapHostRuleArgs;
import com.pulumi.gcp.compute.inputs.URLMapPathMatcherArgs;
import com.pulumi.gcp.compute.TargetHttpProxy;
import com.pulumi.gcp.compute.TargetHttpProxyArgs;
import com.pulumi.gcp.compute.GlobalForwardingRule;
import com.pulumi.gcp.compute.GlobalForwardingRuleArgs;
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 defaultBackendService = new BackendService("defaultBackendService", BackendServiceArgs.builder()
.name("backend")
.portName("http")
.protocol("HTTP")
.timeoutSec(10)
.loadBalancingScheme("EXTERNAL_MANAGED")
.build());
var defaultURLMap = new URLMap("defaultURLMap", URLMapArgs.builder()
.name("url-map-target-proxy")
.description("a description")
.defaultService(defaultBackendService.id())
.hostRules(URLMapHostRuleArgs.builder()
.hosts("mysite.com")
.pathMatcher("allpaths")
.build())
.pathMatchers(URLMapPathMatcherArgs.builder()
.name("allpaths")
.defaultService(defaultBackendService.id())
.pathRules(URLMapPathMatcherPathRuleArgs.builder()
.paths("/*")
.service(defaultBackendService.id())
.build())
.build())
.build());
var defaultTargetHttpProxy = new TargetHttpProxy("defaultTargetHttpProxy", TargetHttpProxyArgs.builder()
.name("target-proxy")
.description("a description")
.urlMap(defaultURLMap.id())
.build());
var default_ = new GlobalForwardingRule("default", GlobalForwardingRuleArgs.builder()
.name("global-rule")
.target(defaultTargetHttpProxy.id())
.portRange("80")
.loadBalancingScheme("EXTERNAL_MANAGED")
.networkTier("PREMIUM")
.build());
}
}
resources:
default:
type: gcp:compute:GlobalForwardingRule
properties:
name: global-rule
target: ${defaultTargetHttpProxy.id}
portRange: '80'
loadBalancingScheme: EXTERNAL_MANAGED
networkTier: PREMIUM
defaultTargetHttpProxy:
type: gcp:compute:TargetHttpProxy
name: default
properties:
name: target-proxy
description: a description
urlMap: ${defaultURLMap.id}
defaultURLMap:
type: gcp:compute:URLMap
name: default
properties:
name: url-map-target-proxy
description: a description
defaultService: ${defaultBackendService.id}
hostRules:
- hosts:
- mysite.com
pathMatcher: allpaths
pathMatchers:
- name: allpaths
defaultService: ${defaultBackendService.id}
pathRules:
- paths:
- /*
service: ${defaultBackendService.id}
defaultBackendService:
type: gcp:compute:BackendService
name: default
properties:
name: backend
portName: http
protocol: HTTP
timeoutSec: 10
loadBalancingScheme: EXTERNAL_MANAGED
The EXTERNAL_MANAGED scheme enables integration with Cloud Armor, Cloud CDN, and other advanced ALB features. The networkTier property controls routing quality; PREMIUM uses Google’s global network for optimal performance.
Connect privately to Google APIs via PSC
Organizations accessing Google APIs from private networks use Private Service Connect forwarding rules with reserved internal IPs.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const network = new gcp.compute.Network("network", {
project: "my-project-name",
name: "my-network",
autoCreateSubnetworks: false,
});
const vpcSubnetwork = new gcp.compute.Subnetwork("vpc_subnetwork", {
project: network.project,
name: "my-subnetwork",
ipCidrRange: "10.2.0.0/16",
region: "us-central1",
network: network.id,
privateIpGoogleAccess: true,
});
const _default = new gcp.compute.GlobalAddress("default", {
project: network.project,
name: "global-psconnect-ip",
addressType: "INTERNAL",
purpose: "PRIVATE_SERVICE_CONNECT",
network: network.id,
address: "100.100.100.106",
});
const defaultGlobalForwardingRule = new gcp.compute.GlobalForwardingRule("default", {
project: network.project,
name: "globalrule",
target: "all-apis",
network: network.id,
ipAddress: _default.id,
loadBalancingScheme: "",
serviceDirectoryRegistrations: {
namespace: "sd-namespace",
serviceDirectoryRegion: "europe-west3",
},
});
import pulumi
import pulumi_gcp as gcp
network = gcp.compute.Network("network",
project="my-project-name",
name="my-network",
auto_create_subnetworks=False)
vpc_subnetwork = gcp.compute.Subnetwork("vpc_subnetwork",
project=network.project,
name="my-subnetwork",
ip_cidr_range="10.2.0.0/16",
region="us-central1",
network=network.id,
private_ip_google_access=True)
default = gcp.compute.GlobalAddress("default",
project=network.project,
name="global-psconnect-ip",
address_type="INTERNAL",
purpose="PRIVATE_SERVICE_CONNECT",
network=network.id,
address="100.100.100.106")
default_global_forwarding_rule = gcp.compute.GlobalForwardingRule("default",
project=network.project,
name="globalrule",
target="all-apis",
network=network.id,
ip_address=default.id,
load_balancing_scheme="",
service_directory_registrations={
"namespace": "sd-namespace",
"service_directory_region": "europe-west3",
})
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 {
network, err := compute.NewNetwork(ctx, "network", &compute.NetworkArgs{
Project: pulumi.String("my-project-name"),
Name: pulumi.String("my-network"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
_, err = compute.NewSubnetwork(ctx, "vpc_subnetwork", &compute.SubnetworkArgs{
Project: network.Project,
Name: pulumi.String("my-subnetwork"),
IpCidrRange: pulumi.String("10.2.0.0/16"),
Region: pulumi.String("us-central1"),
Network: network.ID(),
PrivateIpGoogleAccess: pulumi.Bool(true),
})
if err != nil {
return err
}
_default, err := compute.NewGlobalAddress(ctx, "default", &compute.GlobalAddressArgs{
Project: network.Project,
Name: pulumi.String("global-psconnect-ip"),
AddressType: pulumi.String("INTERNAL"),
Purpose: pulumi.String("PRIVATE_SERVICE_CONNECT"),
Network: network.ID(),
Address: pulumi.String("100.100.100.106"),
})
if err != nil {
return err
}
_, err = compute.NewGlobalForwardingRule(ctx, "default", &compute.GlobalForwardingRuleArgs{
Project: network.Project,
Name: pulumi.String("globalrule"),
Target: pulumi.String("all-apis"),
Network: network.ID(),
IpAddress: _default.ID(),
LoadBalancingScheme: pulumi.String(""),
ServiceDirectoryRegistrations: &compute.GlobalForwardingRuleServiceDirectoryRegistrationsArgs{
Namespace: pulumi.String("sd-namespace"),
ServiceDirectoryRegion: pulumi.String("europe-west3"),
},
})
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 network = new Gcp.Compute.Network("network", new()
{
Project = "my-project-name",
Name = "my-network",
AutoCreateSubnetworks = false,
});
var vpcSubnetwork = new Gcp.Compute.Subnetwork("vpc_subnetwork", new()
{
Project = network.Project,
Name = "my-subnetwork",
IpCidrRange = "10.2.0.0/16",
Region = "us-central1",
Network = network.Id,
PrivateIpGoogleAccess = true,
});
var @default = new Gcp.Compute.GlobalAddress("default", new()
{
Project = network.Project,
Name = "global-psconnect-ip",
AddressType = "INTERNAL",
Purpose = "PRIVATE_SERVICE_CONNECT",
Network = network.Id,
Address = "100.100.100.106",
});
var defaultGlobalForwardingRule = new Gcp.Compute.GlobalForwardingRule("default", new()
{
Project = network.Project,
Name = "globalrule",
Target = "all-apis",
Network = network.Id,
IpAddress = @default.Id,
LoadBalancingScheme = "",
ServiceDirectoryRegistrations = new Gcp.Compute.Inputs.GlobalForwardingRuleServiceDirectoryRegistrationsArgs
{
Namespace = "sd-namespace",
ServiceDirectoryRegion = "europe-west3",
},
});
});
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.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.compute.GlobalAddress;
import com.pulumi.gcp.compute.GlobalAddressArgs;
import com.pulumi.gcp.compute.GlobalForwardingRule;
import com.pulumi.gcp.compute.GlobalForwardingRuleArgs;
import com.pulumi.gcp.compute.inputs.GlobalForwardingRuleServiceDirectoryRegistrationsArgs;
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 network = new Network("network", NetworkArgs.builder()
.project("my-project-name")
.name("my-network")
.autoCreateSubnetworks(false)
.build());
var vpcSubnetwork = new Subnetwork("vpcSubnetwork", SubnetworkArgs.builder()
.project(network.project())
.name("my-subnetwork")
.ipCidrRange("10.2.0.0/16")
.region("us-central1")
.network(network.id())
.privateIpGoogleAccess(true)
.build());
var default_ = new GlobalAddress("default", GlobalAddressArgs.builder()
.project(network.project())
.name("global-psconnect-ip")
.addressType("INTERNAL")
.purpose("PRIVATE_SERVICE_CONNECT")
.network(network.id())
.address("100.100.100.106")
.build());
var defaultGlobalForwardingRule = new GlobalForwardingRule("defaultGlobalForwardingRule", GlobalForwardingRuleArgs.builder()
.project(network.project())
.name("globalrule")
.target("all-apis")
.network(network.id())
.ipAddress(default_.id())
.loadBalancingScheme("")
.serviceDirectoryRegistrations(GlobalForwardingRuleServiceDirectoryRegistrationsArgs.builder()
.namespace("sd-namespace")
.serviceDirectoryRegion("europe-west3")
.build())
.build());
}
}
resources:
network:
type: gcp:compute:Network
properties:
project: my-project-name
name: my-network
autoCreateSubnetworks: false
vpcSubnetwork:
type: gcp:compute:Subnetwork
name: vpc_subnetwork
properties:
project: ${network.project}
name: my-subnetwork
ipCidrRange: 10.2.0.0/16
region: us-central1
network: ${network.id}
privateIpGoogleAccess: true
default:
type: gcp:compute:GlobalAddress
properties:
project: ${network.project}
name: global-psconnect-ip
addressType: INTERNAL
purpose: PRIVATE_SERVICE_CONNECT
network: ${network.id}
address: 100.100.100.106
defaultGlobalForwardingRule:
type: gcp:compute:GlobalForwardingRule
name: default
properties:
project: ${network.project}
name: globalrule
target: all-apis
network: ${network.id}
ipAddress: ${default.id}
loadBalancingScheme: ""
serviceDirectoryRegistrations:
namespace: sd-namespace
serviceDirectoryRegion: europe-west3
The target property accepts special values for Private Service Connect: “all-apis” provides access to all supported Google APIs, while “vpc-sc” limits access to APIs that support VPC Service Controls. The ipAddress must reference a GlobalAddress with purpose PRIVATE_SERVICE_CONNECT. The serviceDirectoryRegistrations property enables service discovery integration.
Beyond these examples
These snippets focus on specific forwarding rule features: HTTP load balancing with target proxies, internal self-managed and external managed schemes, and Private Service Connect for Google APIs. They’re intentionally minimal rather than full load balancing deployments.
The examples reference pre-existing infrastructure such as VPC networks and subnets, backend services, URL maps, and target proxies, and GlobalAddress resources for PSC. They focus on configuring the forwarding rule rather than provisioning the complete load balancing stack.
To keep things focused, common forwarding rule patterns are omitted, including:
- IPv6 configuration (ipVersion)
- Source IP range filtering (sourceIpRanges)
- Backend bucket migration (externalManagedBackendBucketMigrationState)
- Cross-region PSC access (allowPscGlobalAccess)
These omissions are intentional: the goal is to illustrate how each forwarding rule feature is wired, not provide drop-in load balancing modules. See the GlobalForwardingRule resource reference for all available configuration options.
Let's configure GCP Global HTTP Load Balancing Rules
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Load Balancing Configuration
EXTERNAL (default), EXTERNAL_MANAGED, INTERNAL_MANAGED, and INTERNAL_SELF_MANAGED. The scheme determines the forwarding rule type and load balancer behavior.EXTERNAL is the classic load balancing scheme, while EXTERNAL_MANAGED is for newer external Application Load Balancers with advanced features. Use EXTERNAL_MANAGED with networkTier set to PREMIUM for modern deployments.INTERNAL_SELF_MANAGED for service mesh deployments with xDS-compliant clients. Set ipAddress to 0.0.0.0 and optionally configure metadataFilters for routing control.TargetHttpProxy). For Private Service Connect to Google APIs, use all-apis or vpc-sc. For PSC to managed services, use a service attachment URL.IP Address & Networking
ipAddress when: (1) target is targetGrpcProxy with validateForProxyless set to true (use 0.0.0.0), or (2) target is a Private Service Connect Google APIs bundle. Otherwise, it’s optional and Google Cloud assigns an ephemeral IP.100.1.2.3), IPv6 range (2600:1234::/96), full resource URL, partial URL (projects/project_id/regions/region/addresses/address-name), or just the address name. The API always returns the IP address number.PREMIUM (default) uses Google’s global network for optimal performance. STANDARD uses regular ISP networks and costs less. For global forwarding rules, only PREMIUM is valid. If you specify ipAddress, its networkTier must match.Immutability & Updates
ipAddress, ipProtocol, name, network, networkTier, project, serviceDirectoryRegistrations, subnetwork, allowPscGlobalAccess, description, ipVersion, metadataFilters, noAutomateDnsZone, portRange, and sourceIpRanges.target is one of the few properties that can be updated without replacing the resource. You can change which load balancer or service the forwarding rule points to.Private Service Connect
target to all-apis (all Google APIs) or vpc-sc (VPC Service Controls-supported APIs), specify an ipAddress, provide a network, and set loadBalancingScheme to an empty string.Protocols & Ports
TCP, UDP, ESP, AH, SCTP, ICMP. The portRange property requires TCP, UDP, or SCTP, and is only applicable to specific load balancer products (external/internal passthrough and proxy Network Load Balancers, Application Load Balancers, protocol forwarding, Classic VPN). Some products have additional port restrictions.metadataFilters only works when loadBalancingScheme is set to INTERNAL_SELF_MANAGED. It restricts routing configuration to xDS-compliant clients based on node metadata matching.Using a different cloud?
Explore networking guides for other cloud providers: