The gcp:compute/forwardingRule:ForwardingRule resource, part of the Pulumi GCP provider, defines forwarding rules that route traffic to load balancer backends, target pools, or Private Service Connect endpoints based on IP address, protocol, and port configuration. This guide focuses on three capabilities: external and internal load balancing, Private Service Connect connectivity, and source IP-based traffic steering.
Forwarding rules reference backend services, target pools, or service attachments, and typically require VPC networks, subnets, and reserved IP addresses. The examples are intentionally small. Combine them with your own backend infrastructure and network configuration.
Route external traffic to a backend service
Most external load balancers route internet traffic to a regional backend service that distributes requests across instance groups.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const hc = new gcp.compute.RegionHealthCheck("hc", {
name: "check-website-backend",
checkIntervalSec: 1,
timeoutSec: 1,
region: "us-central1",
tcpHealthCheck: {
port: 80,
},
});
const backend = new gcp.compute.RegionBackendService("backend", {
name: "website-backend",
region: "us-central1",
loadBalancingScheme: "EXTERNAL",
healthChecks: hc.id,
});
// Forwarding rule for External Network Load Balancing using Backend Services
const _default = new gcp.compute.ForwardingRule("default", {
name: "website-forwarding-rule",
region: "us-central1",
portRange: "80",
backendService: backend.id,
});
import pulumi
import pulumi_gcp as gcp
hc = gcp.compute.RegionHealthCheck("hc",
name="check-website-backend",
check_interval_sec=1,
timeout_sec=1,
region="us-central1",
tcp_health_check={
"port": 80,
})
backend = gcp.compute.RegionBackendService("backend",
name="website-backend",
region="us-central1",
load_balancing_scheme="EXTERNAL",
health_checks=hc.id)
# Forwarding rule for External Network Load Balancing using Backend Services
default = gcp.compute.ForwardingRule("default",
name="website-forwarding-rule",
region="us-central1",
port_range="80",
backend_service=backend.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 {
hc, err := compute.NewRegionHealthCheck(ctx, "hc", &compute.RegionHealthCheckArgs{
Name: pulumi.String("check-website-backend"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
Region: pulumi.String("us-central1"),
TcpHealthCheck: &compute.RegionHealthCheckTcpHealthCheckArgs{
Port: pulumi.Int(80),
},
})
if err != nil {
return err
}
backend, err := compute.NewRegionBackendService(ctx, "backend", &compute.RegionBackendServiceArgs{
Name: pulumi.String("website-backend"),
Region: pulumi.String("us-central1"),
LoadBalancingScheme: pulumi.String("EXTERNAL"),
HealthChecks: hc.ID(),
})
if err != nil {
return err
}
// Forwarding rule for External Network Load Balancing using Backend Services
_, err = compute.NewForwardingRule(ctx, "default", &compute.ForwardingRuleArgs{
Name: pulumi.String("website-forwarding-rule"),
Region: pulumi.String("us-central1"),
PortRange: pulumi.String("80"),
BackendService: backend.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 hc = new Gcp.Compute.RegionHealthCheck("hc", new()
{
Name = "check-website-backend",
CheckIntervalSec = 1,
TimeoutSec = 1,
Region = "us-central1",
TcpHealthCheck = new Gcp.Compute.Inputs.RegionHealthCheckTcpHealthCheckArgs
{
Port = 80,
},
});
var backend = new Gcp.Compute.RegionBackendService("backend", new()
{
Name = "website-backend",
Region = "us-central1",
LoadBalancingScheme = "EXTERNAL",
HealthChecks = hc.Id,
});
// Forwarding rule for External Network Load Balancing using Backend Services
var @default = new Gcp.Compute.ForwardingRule("default", new()
{
Name = "website-forwarding-rule",
Region = "us-central1",
PortRange = "80",
BackendService = backend.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.RegionHealthCheckTcpHealthCheckArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
import com.pulumi.gcp.compute.ForwardingRule;
import com.pulumi.gcp.compute.ForwardingRuleArgs;
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 hc = new RegionHealthCheck("hc", RegionHealthCheckArgs.builder()
.name("check-website-backend")
.checkIntervalSec(1)
.timeoutSec(1)
.region("us-central1")
.tcpHealthCheck(RegionHealthCheckTcpHealthCheckArgs.builder()
.port(80)
.build())
.build());
var backend = new RegionBackendService("backend", RegionBackendServiceArgs.builder()
.name("website-backend")
.region("us-central1")
.loadBalancingScheme("EXTERNAL")
.healthChecks(hc.id())
.build());
// Forwarding rule for External Network Load Balancing using Backend Services
var default_ = new ForwardingRule("default", ForwardingRuleArgs.builder()
.name("website-forwarding-rule")
.region("us-central1")
.portRange("80")
.backendService(backend.id())
.build());
}
}
resources:
# Forwarding rule for External Network Load Balancing using Backend Services
default:
type: gcp:compute:ForwardingRule
properties:
name: website-forwarding-rule
region: us-central1
portRange: 80
backendService: ${backend.id}
backend:
type: gcp:compute:RegionBackendService
properties:
name: website-backend
region: us-central1
loadBalancingScheme: EXTERNAL
healthChecks: ${hc.id}
hc:
type: gcp:compute:RegionHealthCheck
properties:
name: check-website-backend
checkIntervalSec: 1
timeoutSec: 1
region: us-central1
tcpHealthCheck:
port: '80'
When traffic arrives at the forwarding rule’s IP address on the specified port, GCP routes it to the backend service. The loadBalancingScheme defaults to EXTERNAL for internet-facing load balancers. The portRange property specifies which ports accept traffic; here, only port 80 is open.
Route internal VPC traffic to backend services
Applications within a VPC need private load balancing to distribute traffic across internal services without internet exposure.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const hc = new gcp.compute.HealthCheck("hc", {
name: "check-website-backend",
checkIntervalSec: 1,
timeoutSec: 1,
tcpHealthCheck: {
port: 80,
},
});
const backend = new gcp.compute.RegionBackendService("backend", {
name: "website-backend",
region: "us-central1",
healthChecks: hc.id,
});
const defaultNetwork = new gcp.compute.Network("default", {
name: "website-net",
autoCreateSubnetworks: false,
});
const defaultSubnetwork = new gcp.compute.Subnetwork("default", {
name: "website-net",
ipCidrRange: "10.0.0.0/16",
region: "us-central1",
network: defaultNetwork.id,
});
// Forwarding rule for Internal Load Balancing
const _default = new gcp.compute.ForwardingRule("default", {
name: "website-forwarding-rule",
region: "us-central1",
loadBalancingScheme: "INTERNAL",
backendService: backend.id,
allPorts: true,
network: defaultNetwork.name,
subnetwork: defaultSubnetwork.name,
ipVersion: "IPV4",
});
import pulumi
import pulumi_gcp as gcp
hc = gcp.compute.HealthCheck("hc",
name="check-website-backend",
check_interval_sec=1,
timeout_sec=1,
tcp_health_check={
"port": 80,
})
backend = gcp.compute.RegionBackendService("backend",
name="website-backend",
region="us-central1",
health_checks=hc.id)
default_network = gcp.compute.Network("default",
name="website-net",
auto_create_subnetworks=False)
default_subnetwork = gcp.compute.Subnetwork("default",
name="website-net",
ip_cidr_range="10.0.0.0/16",
region="us-central1",
network=default_network.id)
# Forwarding rule for Internal Load Balancing
default = gcp.compute.ForwardingRule("default",
name="website-forwarding-rule",
region="us-central1",
load_balancing_scheme="INTERNAL",
backend_service=backend.id,
all_ports=True,
network=default_network.name,
subnetwork=default_subnetwork.name,
ip_version="IPV4")
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 {
hc, err := compute.NewHealthCheck(ctx, "hc", &compute.HealthCheckArgs{
Name: pulumi.String("check-website-backend"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
TcpHealthCheck: &compute.HealthCheckTcpHealthCheckArgs{
Port: pulumi.Int(80),
},
})
if err != nil {
return err
}
backend, err := compute.NewRegionBackendService(ctx, "backend", &compute.RegionBackendServiceArgs{
Name: pulumi.String("website-backend"),
Region: pulumi.String("us-central1"),
HealthChecks: hc.ID(),
})
if err != nil {
return err
}
defaultNetwork, err := compute.NewNetwork(ctx, "default", &compute.NetworkArgs{
Name: pulumi.String("website-net"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
defaultSubnetwork, err := compute.NewSubnetwork(ctx, "default", &compute.SubnetworkArgs{
Name: pulumi.String("website-net"),
IpCidrRange: pulumi.String("10.0.0.0/16"),
Region: pulumi.String("us-central1"),
Network: defaultNetwork.ID(),
})
if err != nil {
return err
}
// Forwarding rule for Internal Load Balancing
_, err = compute.NewForwardingRule(ctx, "default", &compute.ForwardingRuleArgs{
Name: pulumi.String("website-forwarding-rule"),
Region: pulumi.String("us-central1"),
LoadBalancingScheme: pulumi.String("INTERNAL"),
BackendService: backend.ID(),
AllPorts: pulumi.Bool(true),
Network: defaultNetwork.Name,
Subnetwork: defaultSubnetwork.Name,
IpVersion: pulumi.String("IPV4"),
})
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 hc = new Gcp.Compute.HealthCheck("hc", new()
{
Name = "check-website-backend",
CheckIntervalSec = 1,
TimeoutSec = 1,
TcpHealthCheck = new Gcp.Compute.Inputs.HealthCheckTcpHealthCheckArgs
{
Port = 80,
},
});
var backend = new Gcp.Compute.RegionBackendService("backend", new()
{
Name = "website-backend",
Region = "us-central1",
HealthChecks = hc.Id,
});
var defaultNetwork = new Gcp.Compute.Network("default", new()
{
Name = "website-net",
AutoCreateSubnetworks = false,
});
var defaultSubnetwork = new Gcp.Compute.Subnetwork("default", new()
{
Name = "website-net",
IpCidrRange = "10.0.0.0/16",
Region = "us-central1",
Network = defaultNetwork.Id,
});
// Forwarding rule for Internal Load Balancing
var @default = new Gcp.Compute.ForwardingRule("default", new()
{
Name = "website-forwarding-rule",
Region = "us-central1",
LoadBalancingScheme = "INTERNAL",
BackendService = backend.Id,
AllPorts = true,
Network = defaultNetwork.Name,
Subnetwork = defaultSubnetwork.Name,
IpVersion = "IPV4",
});
});
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 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.ForwardingRule;
import com.pulumi.gcp.compute.ForwardingRuleArgs;
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 hc = new HealthCheck("hc", HealthCheckArgs.builder()
.name("check-website-backend")
.checkIntervalSec(1)
.timeoutSec(1)
.tcpHealthCheck(HealthCheckTcpHealthCheckArgs.builder()
.port(80)
.build())
.build());
var backend = new RegionBackendService("backend", RegionBackendServiceArgs.builder()
.name("website-backend")
.region("us-central1")
.healthChecks(hc.id())
.build());
var defaultNetwork = new Network("defaultNetwork", NetworkArgs.builder()
.name("website-net")
.autoCreateSubnetworks(false)
.build());
var defaultSubnetwork = new Subnetwork("defaultSubnetwork", SubnetworkArgs.builder()
.name("website-net")
.ipCidrRange("10.0.0.0/16")
.region("us-central1")
.network(defaultNetwork.id())
.build());
// Forwarding rule for Internal Load Balancing
var default_ = new ForwardingRule("default", ForwardingRuleArgs.builder()
.name("website-forwarding-rule")
.region("us-central1")
.loadBalancingScheme("INTERNAL")
.backendService(backend.id())
.allPorts(true)
.network(defaultNetwork.name())
.subnetwork(defaultSubnetwork.name())
.ipVersion("IPV4")
.build());
}
}
resources:
# Forwarding rule for Internal Load Balancing
default:
type: gcp:compute:ForwardingRule
properties:
name: website-forwarding-rule
region: us-central1
loadBalancingScheme: INTERNAL
backendService: ${backend.id}
allPorts: true
network: ${defaultNetwork.name}
subnetwork: ${defaultSubnetwork.name}
ipVersion: IPV4
backend:
type: gcp:compute:RegionBackendService
properties:
name: website-backend
region: us-central1
healthChecks: ${hc.id}
hc:
type: gcp:compute:HealthCheck
properties:
name: check-website-backend
checkIntervalSec: 1
timeoutSec: 1
tcpHealthCheck:
port: '80'
defaultNetwork:
type: gcp:compute:Network
name: default
properties:
name: website-net
autoCreateSubnetworks: false
defaultSubnetwork:
type: gcp:compute:Subnetwork
name: default
properties:
name: website-net
ipCidrRange: 10.0.0.0/16
region: us-central1
network: ${defaultNetwork.id}
Setting loadBalancingScheme to INTERNAL creates a private load balancer accessible only within the VPC. The network and subnetwork properties place the forwarding rule in your VPC. The allPorts property accepts traffic on any port, simplifying configuration when backends listen on multiple ports.
Forward traffic to a target pool
Legacy network load balancing uses target pools to group instances that receive traffic directly.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const defaultTargetPool = new gcp.compute.TargetPool("default", {name: "website-target-pool"});
const _default = new gcp.compute.ForwardingRule("default", {
name: "website-forwarding-rule",
target: defaultTargetPool.id,
portRange: "80",
});
import pulumi
import pulumi_gcp as gcp
default_target_pool = gcp.compute.TargetPool("default", name="website-target-pool")
default = gcp.compute.ForwardingRule("default",
name="website-forwarding-rule",
target=default_target_pool.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 {
defaultTargetPool, err := compute.NewTargetPool(ctx, "default", &compute.TargetPoolArgs{
Name: pulumi.String("website-target-pool"),
})
if err != nil {
return err
}
_, err = compute.NewForwardingRule(ctx, "default", &compute.ForwardingRuleArgs{
Name: pulumi.String("website-forwarding-rule"),
Target: defaultTargetPool.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 defaultTargetPool = new Gcp.Compute.TargetPool("default", new()
{
Name = "website-target-pool",
});
var @default = new Gcp.Compute.ForwardingRule("default", new()
{
Name = "website-forwarding-rule",
Target = defaultTargetPool.Id,
PortRange = "80",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.TargetPool;
import com.pulumi.gcp.compute.TargetPoolArgs;
import com.pulumi.gcp.compute.ForwardingRule;
import com.pulumi.gcp.compute.ForwardingRuleArgs;
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 defaultTargetPool = new TargetPool("defaultTargetPool", TargetPoolArgs.builder()
.name("website-target-pool")
.build());
var default_ = new ForwardingRule("default", ForwardingRuleArgs.builder()
.name("website-forwarding-rule")
.target(defaultTargetPool.id())
.portRange("80")
.build());
}
}
resources:
default:
type: gcp:compute:ForwardingRule
properties:
name: website-forwarding-rule
target: ${defaultTargetPool.id}
portRange: '80'
defaultTargetPool:
type: gcp:compute:TargetPool
name: default
properties:
name: website-target-pool
The target property points to a TargetPool resource instead of a backend service. This simpler configuration works for basic load balancing scenarios where you don’t need the advanced features of backend services like health checks or session affinity.
Connect to services via Private Service Connect
Private Service Connect enables private connectivity to services across VPCs or projects without internet exposure or VPC peering.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
// Consumer service endpoint
const consumerNet = new gcp.compute.Network("consumer_net", {
name: "consumer-net",
autoCreateSubnetworks: false,
});
const consumerSubnet = new gcp.compute.Subnetwork("consumer_subnet", {
name: "consumer-net",
ipCidrRange: "10.0.0.0/16",
region: "us-central1",
network: consumerNet.id,
});
const consumerAddress = new gcp.compute.Address("consumer_address", {
name: "website-ip-1",
region: "us-central1",
subnetwork: consumerSubnet.id,
addressType: "INTERNAL",
});
// Producer service attachment
const producerNet = new gcp.compute.Network("producer_net", {
name: "producer-net",
autoCreateSubnetworks: false,
});
const pscProducerSubnet = new gcp.compute.Subnetwork("psc_producer_subnet", {
name: "producer-psc-net",
ipCidrRange: "10.1.0.0/16",
region: "us-central1",
purpose: "PRIVATE_SERVICE_CONNECT",
network: producerNet.id,
});
const producerSubnet = new gcp.compute.Subnetwork("producer_subnet", {
name: "producer-net",
ipCidrRange: "10.0.0.0/16",
region: "us-central1",
network: producerNet.id,
});
const producerServiceHealthCheck = new gcp.compute.HealthCheck("producer_service_health_check", {
name: "producer-service-health-check",
checkIntervalSec: 1,
timeoutSec: 1,
tcpHealthCheck: {
port: 80,
},
});
const producerServiceBackend = new gcp.compute.RegionBackendService("producer_service_backend", {
name: "producer-service-backend",
region: "us-central1",
healthChecks: producerServiceHealthCheck.id,
});
const producerTargetService = new gcp.compute.ForwardingRule("producer_target_service", {
name: "producer-forwarding-rule",
region: "us-central1",
loadBalancingScheme: "INTERNAL",
backendService: producerServiceBackend.id,
allPorts: true,
network: producerNet.name,
subnetwork: producerSubnet.name,
});
const producerServiceAttachment = new gcp.compute.ServiceAttachment("producer_service_attachment", {
name: "producer-service",
region: "us-central1",
description: "A service attachment configured with Terraform",
enableProxyProtocol: true,
connectionPreference: "ACCEPT_AUTOMATIC",
natSubnets: [pscProducerSubnet.name],
targetService: producerTargetService.id,
});
// Forwarding rule for VPC private service connect
const _default = new gcp.compute.ForwardingRule("default", {
name: "psc-endpoint",
region: "us-central1",
loadBalancingScheme: "",
target: producerServiceAttachment.id,
network: consumerNet.name,
ipAddress: consumerAddress.id,
allowPscGlobalAccess: true,
});
import pulumi
import pulumi_gcp as gcp
# Consumer service endpoint
consumer_net = gcp.compute.Network("consumer_net",
name="consumer-net",
auto_create_subnetworks=False)
consumer_subnet = gcp.compute.Subnetwork("consumer_subnet",
name="consumer-net",
ip_cidr_range="10.0.0.0/16",
region="us-central1",
network=consumer_net.id)
consumer_address = gcp.compute.Address("consumer_address",
name="website-ip-1",
region="us-central1",
subnetwork=consumer_subnet.id,
address_type="INTERNAL")
# Producer service attachment
producer_net = gcp.compute.Network("producer_net",
name="producer-net",
auto_create_subnetworks=False)
psc_producer_subnet = gcp.compute.Subnetwork("psc_producer_subnet",
name="producer-psc-net",
ip_cidr_range="10.1.0.0/16",
region="us-central1",
purpose="PRIVATE_SERVICE_CONNECT",
network=producer_net.id)
producer_subnet = gcp.compute.Subnetwork("producer_subnet",
name="producer-net",
ip_cidr_range="10.0.0.0/16",
region="us-central1",
network=producer_net.id)
producer_service_health_check = gcp.compute.HealthCheck("producer_service_health_check",
name="producer-service-health-check",
check_interval_sec=1,
timeout_sec=1,
tcp_health_check={
"port": 80,
})
producer_service_backend = gcp.compute.RegionBackendService("producer_service_backend",
name="producer-service-backend",
region="us-central1",
health_checks=producer_service_health_check.id)
producer_target_service = gcp.compute.ForwardingRule("producer_target_service",
name="producer-forwarding-rule",
region="us-central1",
load_balancing_scheme="INTERNAL",
backend_service=producer_service_backend.id,
all_ports=True,
network=producer_net.name,
subnetwork=producer_subnet.name)
producer_service_attachment = gcp.compute.ServiceAttachment("producer_service_attachment",
name="producer-service",
region="us-central1",
description="A service attachment configured with Terraform",
enable_proxy_protocol=True,
connection_preference="ACCEPT_AUTOMATIC",
nat_subnets=[psc_producer_subnet.name],
target_service=producer_target_service.id)
# Forwarding rule for VPC private service connect
default = gcp.compute.ForwardingRule("default",
name="psc-endpoint",
region="us-central1",
load_balancing_scheme="",
target=producer_service_attachment.id,
network=consumer_net.name,
ip_address=consumer_address.id,
allow_psc_global_access=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 {
// Consumer service endpoint
consumerNet, err := compute.NewNetwork(ctx, "consumer_net", &compute.NetworkArgs{
Name: pulumi.String("consumer-net"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
consumerSubnet, err := compute.NewSubnetwork(ctx, "consumer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("consumer-net"),
IpCidrRange: pulumi.String("10.0.0.0/16"),
Region: pulumi.String("us-central1"),
Network: consumerNet.ID(),
})
if err != nil {
return err
}
consumerAddress, err := compute.NewAddress(ctx, "consumer_address", &compute.AddressArgs{
Name: pulumi.String("website-ip-1"),
Region: pulumi.String("us-central1"),
Subnetwork: consumerSubnet.ID(),
AddressType: pulumi.String("INTERNAL"),
})
if err != nil {
return err
}
// Producer service attachment
producerNet, err := compute.NewNetwork(ctx, "producer_net", &compute.NetworkArgs{
Name: pulumi.String("producer-net"),
AutoCreateSubnetworks: pulumi.Bool(false),
})
if err != nil {
return err
}
pscProducerSubnet, err := compute.NewSubnetwork(ctx, "psc_producer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("producer-psc-net"),
IpCidrRange: pulumi.String("10.1.0.0/16"),
Region: pulumi.String("us-central1"),
Purpose: pulumi.String("PRIVATE_SERVICE_CONNECT"),
Network: producerNet.ID(),
})
if err != nil {
return err
}
producerSubnet, err := compute.NewSubnetwork(ctx, "producer_subnet", &compute.SubnetworkArgs{
Name: pulumi.String("producer-net"),
IpCidrRange: pulumi.String("10.0.0.0/16"),
Region: pulumi.String("us-central1"),
Network: producerNet.ID(),
})
if err != nil {
return err
}
producerServiceHealthCheck, err := compute.NewHealthCheck(ctx, "producer_service_health_check", &compute.HealthCheckArgs{
Name: pulumi.String("producer-service-health-check"),
CheckIntervalSec: pulumi.Int(1),
TimeoutSec: pulumi.Int(1),
TcpHealthCheck: &compute.HealthCheckTcpHealthCheckArgs{
Port: pulumi.Int(80),
},
})
if err != nil {
return err
}
producerServiceBackend, err := compute.NewRegionBackendService(ctx, "producer_service_backend", &compute.RegionBackendServiceArgs{
Name: pulumi.String("producer-service-backend"),
Region: pulumi.String("us-central1"),
HealthChecks: producerServiceHealthCheck.ID(),
})
if err != nil {
return err
}
producerTargetService, err := compute.NewForwardingRule(ctx, "producer_target_service", &compute.ForwardingRuleArgs{
Name: pulumi.String("producer-forwarding-rule"),
Region: pulumi.String("us-central1"),
LoadBalancingScheme: pulumi.String("INTERNAL"),
BackendService: producerServiceBackend.ID(),
AllPorts: pulumi.Bool(true),
Network: producerNet.Name,
Subnetwork: producerSubnet.Name,
})
if err != nil {
return err
}
producerServiceAttachment, err := compute.NewServiceAttachment(ctx, "producer_service_attachment", &compute.ServiceAttachmentArgs{
Name: pulumi.String("producer-service"),
Region: pulumi.String("us-central1"),
Description: pulumi.String("A service attachment configured with Terraform"),
EnableProxyProtocol: pulumi.Bool(true),
ConnectionPreference: pulumi.String("ACCEPT_AUTOMATIC"),
NatSubnets: pulumi.StringArray{
pscProducerSubnet.Name,
},
TargetService: producerTargetService.ID(),
})
if err != nil {
return err
}
// Forwarding rule for VPC private service connect
_, err = compute.NewForwardingRule(ctx, "default", &compute.ForwardingRuleArgs{
Name: pulumi.String("psc-endpoint"),
Region: pulumi.String("us-central1"),
LoadBalancingScheme: pulumi.String(""),
Target: producerServiceAttachment.ID(),
Network: consumerNet.Name,
IpAddress: consumerAddress.ID(),
AllowPscGlobalAccess: 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(() =>
{
// Consumer service endpoint
var consumerNet = new Gcp.Compute.Network("consumer_net", new()
{
Name = "consumer-net",
AutoCreateSubnetworks = false,
});
var consumerSubnet = new Gcp.Compute.Subnetwork("consumer_subnet", new()
{
Name = "consumer-net",
IpCidrRange = "10.0.0.0/16",
Region = "us-central1",
Network = consumerNet.Id,
});
var consumerAddress = new Gcp.Compute.Address("consumer_address", new()
{
Name = "website-ip-1",
Region = "us-central1",
Subnetwork = consumerSubnet.Id,
AddressType = "INTERNAL",
});
// Producer service attachment
var producerNet = new Gcp.Compute.Network("producer_net", new()
{
Name = "producer-net",
AutoCreateSubnetworks = false,
});
var pscProducerSubnet = new Gcp.Compute.Subnetwork("psc_producer_subnet", new()
{
Name = "producer-psc-net",
IpCidrRange = "10.1.0.0/16",
Region = "us-central1",
Purpose = "PRIVATE_SERVICE_CONNECT",
Network = producerNet.Id,
});
var producerSubnet = new Gcp.Compute.Subnetwork("producer_subnet", new()
{
Name = "producer-net",
IpCidrRange = "10.0.0.0/16",
Region = "us-central1",
Network = producerNet.Id,
});
var producerServiceHealthCheck = new Gcp.Compute.HealthCheck("producer_service_health_check", new()
{
Name = "producer-service-health-check",
CheckIntervalSec = 1,
TimeoutSec = 1,
TcpHealthCheck = new Gcp.Compute.Inputs.HealthCheckTcpHealthCheckArgs
{
Port = 80,
},
});
var producerServiceBackend = new Gcp.Compute.RegionBackendService("producer_service_backend", new()
{
Name = "producer-service-backend",
Region = "us-central1",
HealthChecks = producerServiceHealthCheck.Id,
});
var producerTargetService = new Gcp.Compute.ForwardingRule("producer_target_service", new()
{
Name = "producer-forwarding-rule",
Region = "us-central1",
LoadBalancingScheme = "INTERNAL",
BackendService = producerServiceBackend.Id,
AllPorts = true,
Network = producerNet.Name,
Subnetwork = producerSubnet.Name,
});
var producerServiceAttachment = new Gcp.Compute.ServiceAttachment("producer_service_attachment", new()
{
Name = "producer-service",
Region = "us-central1",
Description = "A service attachment configured with Terraform",
EnableProxyProtocol = true,
ConnectionPreference = "ACCEPT_AUTOMATIC",
NatSubnets = new[]
{
pscProducerSubnet.Name,
},
TargetService = producerTargetService.Id,
});
// Forwarding rule for VPC private service connect
var @default = new Gcp.Compute.ForwardingRule("default", new()
{
Name = "psc-endpoint",
Region = "us-central1",
LoadBalancingScheme = "",
Target = producerServiceAttachment.Id,
Network = consumerNet.Name,
IpAddress = consumerAddress.Id,
AllowPscGlobalAccess = true,
});
});
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.Address;
import com.pulumi.gcp.compute.AddressArgs;
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 com.pulumi.gcp.compute.ForwardingRule;
import com.pulumi.gcp.compute.ForwardingRuleArgs;
import com.pulumi.gcp.compute.ServiceAttachment;
import com.pulumi.gcp.compute.ServiceAttachmentArgs;
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) {
// Consumer service endpoint
var consumerNet = new Network("consumerNet", NetworkArgs.builder()
.name("consumer-net")
.autoCreateSubnetworks(false)
.build());
var consumerSubnet = new Subnetwork("consumerSubnet", SubnetworkArgs.builder()
.name("consumer-net")
.ipCidrRange("10.0.0.0/16")
.region("us-central1")
.network(consumerNet.id())
.build());
var consumerAddress = new Address("consumerAddress", AddressArgs.builder()
.name("website-ip-1")
.region("us-central1")
.subnetwork(consumerSubnet.id())
.addressType("INTERNAL")
.build());
// Producer service attachment
var producerNet = new Network("producerNet", NetworkArgs.builder()
.name("producer-net")
.autoCreateSubnetworks(false)
.build());
var pscProducerSubnet = new Subnetwork("pscProducerSubnet", SubnetworkArgs.builder()
.name("producer-psc-net")
.ipCidrRange("10.1.0.0/16")
.region("us-central1")
.purpose("PRIVATE_SERVICE_CONNECT")
.network(producerNet.id())
.build());
var producerSubnet = new Subnetwork("producerSubnet", SubnetworkArgs.builder()
.name("producer-net")
.ipCidrRange("10.0.0.0/16")
.region("us-central1")
.network(producerNet.id())
.build());
var producerServiceHealthCheck = new HealthCheck("producerServiceHealthCheck", HealthCheckArgs.builder()
.name("producer-service-health-check")
.checkIntervalSec(1)
.timeoutSec(1)
.tcpHealthCheck(HealthCheckTcpHealthCheckArgs.builder()
.port(80)
.build())
.build());
var producerServiceBackend = new RegionBackendService("producerServiceBackend", RegionBackendServiceArgs.builder()
.name("producer-service-backend")
.region("us-central1")
.healthChecks(producerServiceHealthCheck.id())
.build());
var producerTargetService = new ForwardingRule("producerTargetService", ForwardingRuleArgs.builder()
.name("producer-forwarding-rule")
.region("us-central1")
.loadBalancingScheme("INTERNAL")
.backendService(producerServiceBackend.id())
.allPorts(true)
.network(producerNet.name())
.subnetwork(producerSubnet.name())
.build());
var producerServiceAttachment = new ServiceAttachment("producerServiceAttachment", ServiceAttachmentArgs.builder()
.name("producer-service")
.region("us-central1")
.description("A service attachment configured with Terraform")
.enableProxyProtocol(true)
.connectionPreference("ACCEPT_AUTOMATIC")
.natSubnets(pscProducerSubnet.name())
.targetService(producerTargetService.id())
.build());
// Forwarding rule for VPC private service connect
var default_ = new ForwardingRule("default", ForwardingRuleArgs.builder()
.name("psc-endpoint")
.region("us-central1")
.loadBalancingScheme("")
.target(producerServiceAttachment.id())
.network(consumerNet.name())
.ipAddress(consumerAddress.id())
.allowPscGlobalAccess(true)
.build());
}
}
resources:
# Forwarding rule for VPC private service connect
default:
type: gcp:compute:ForwardingRule
properties:
name: psc-endpoint
region: us-central1
loadBalancingScheme: ""
target: ${producerServiceAttachment.id}
network: ${consumerNet.name}
ipAddress: ${consumerAddress.id}
allowPscGlobalAccess: true
# Consumer service endpoint
consumerNet:
type: gcp:compute:Network
name: consumer_net
properties:
name: consumer-net
autoCreateSubnetworks: false
consumerSubnet:
type: gcp:compute:Subnetwork
name: consumer_subnet
properties:
name: consumer-net
ipCidrRange: 10.0.0.0/16
region: us-central1
network: ${consumerNet.id}
consumerAddress:
type: gcp:compute:Address
name: consumer_address
properties:
name: website-ip-1
region: us-central1
subnetwork: ${consumerSubnet.id}
addressType: INTERNAL
# Producer service attachment
producerNet:
type: gcp:compute:Network
name: producer_net
properties:
name: producer-net
autoCreateSubnetworks: false
producerSubnet:
type: gcp:compute:Subnetwork
name: producer_subnet
properties:
name: producer-net
ipCidrRange: 10.0.0.0/16
region: us-central1
network: ${producerNet.id}
pscProducerSubnet:
type: gcp:compute:Subnetwork
name: psc_producer_subnet
properties:
name: producer-psc-net
ipCidrRange: 10.1.0.0/16
region: us-central1
purpose: PRIVATE_SERVICE_CONNECT
network: ${producerNet.id}
producerServiceAttachment:
type: gcp:compute:ServiceAttachment
name: producer_service_attachment
properties:
name: producer-service
region: us-central1
description: A service attachment configured with Terraform
enableProxyProtocol: true
connectionPreference: ACCEPT_AUTOMATIC
natSubnets:
- ${pscProducerSubnet.name}
targetService: ${producerTargetService.id}
producerTargetService:
type: gcp:compute:ForwardingRule
name: producer_target_service
properties:
name: producer-forwarding-rule
region: us-central1
loadBalancingScheme: INTERNAL
backendService: ${producerServiceBackend.id}
allPorts: true
network: ${producerNet.name}
subnetwork: ${producerSubnet.name}
producerServiceBackend:
type: gcp:compute:RegionBackendService
name: producer_service_backend
properties:
name: producer-service-backend
region: us-central1
healthChecks: ${producerServiceHealthCheck.id}
producerServiceHealthCheck:
type: gcp:compute:HealthCheck
name: producer_service_health_check
properties:
name: producer-service-health-check
checkIntervalSec: 1
timeoutSec: 1
tcpHealthCheck:
port: '80'
The target property references a ServiceAttachment from the producer service. Setting loadBalancingScheme to an empty string ("") indicates this is a Private Service Connect endpoint, not a traditional load balancer. The allowPscGlobalAccess property enables cross-region connectivity to the producer service.
Route traffic based on source IP ranges
Traffic steering routes requests from specific source IP ranges to different backends, enabling geographic routing or client-specific load balancing.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const basic = new gcp.compute.Address("basic", {
name: "website-ip",
region: "us-central1",
});
const external = new gcp.compute.RegionBackendService("external", {
name: "service-backend",
region: "us-central1",
loadBalancingScheme: "EXTERNAL",
});
const externalForwardingRule = new gcp.compute.ForwardingRule("external", {
name: "external-forwarding-rule",
region: "us-central1",
ipAddress: basic.address,
backendService: external.selfLink,
loadBalancingScheme: "EXTERNAL",
});
const steering = new gcp.compute.ForwardingRule("steering", {
name: "steering-rule",
region: "us-central1",
ipAddress: basic.address,
backendService: external.selfLink,
loadBalancingScheme: "EXTERNAL",
sourceIpRanges: [
"34.121.88.0/24",
"35.187.239.137",
],
}, {
dependsOn: [externalForwardingRule],
});
import pulumi
import pulumi_gcp as gcp
basic = gcp.compute.Address("basic",
name="website-ip",
region="us-central1")
external = gcp.compute.RegionBackendService("external",
name="service-backend",
region="us-central1",
load_balancing_scheme="EXTERNAL")
external_forwarding_rule = gcp.compute.ForwardingRule("external",
name="external-forwarding-rule",
region="us-central1",
ip_address=basic.address,
backend_service=external.self_link,
load_balancing_scheme="EXTERNAL")
steering = gcp.compute.ForwardingRule("steering",
name="steering-rule",
region="us-central1",
ip_address=basic.address,
backend_service=external.self_link,
load_balancing_scheme="EXTERNAL",
source_ip_ranges=[
"34.121.88.0/24",
"35.187.239.137",
],
opts = pulumi.ResourceOptions(depends_on=[external_forwarding_rule]))
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 {
basic, err := compute.NewAddress(ctx, "basic", &compute.AddressArgs{
Name: pulumi.String("website-ip"),
Region: pulumi.String("us-central1"),
})
if err != nil {
return err
}
external, err := compute.NewRegionBackendService(ctx, "external", &compute.RegionBackendServiceArgs{
Name: pulumi.String("service-backend"),
Region: pulumi.String("us-central1"),
LoadBalancingScheme: pulumi.String("EXTERNAL"),
})
if err != nil {
return err
}
externalForwardingRule, err := compute.NewForwardingRule(ctx, "external", &compute.ForwardingRuleArgs{
Name: pulumi.String("external-forwarding-rule"),
Region: pulumi.String("us-central1"),
IpAddress: basic.Address,
BackendService: external.SelfLink,
LoadBalancingScheme: pulumi.String("EXTERNAL"),
})
if err != nil {
return err
}
_, err = compute.NewForwardingRule(ctx, "steering", &compute.ForwardingRuleArgs{
Name: pulumi.String("steering-rule"),
Region: pulumi.String("us-central1"),
IpAddress: basic.Address,
BackendService: external.SelfLink,
LoadBalancingScheme: pulumi.String("EXTERNAL"),
SourceIpRanges: pulumi.StringArray{
pulumi.String("34.121.88.0/24"),
pulumi.String("35.187.239.137"),
},
}, pulumi.DependsOn([]pulumi.Resource{
externalForwardingRule,
}))
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 basic = new Gcp.Compute.Address("basic", new()
{
Name = "website-ip",
Region = "us-central1",
});
var external = new Gcp.Compute.RegionBackendService("external", new()
{
Name = "service-backend",
Region = "us-central1",
LoadBalancingScheme = "EXTERNAL",
});
var externalForwardingRule = new Gcp.Compute.ForwardingRule("external", new()
{
Name = "external-forwarding-rule",
Region = "us-central1",
IpAddress = basic.IPAddress,
BackendService = external.SelfLink,
LoadBalancingScheme = "EXTERNAL",
});
var steering = new Gcp.Compute.ForwardingRule("steering", new()
{
Name = "steering-rule",
Region = "us-central1",
IpAddress = basic.IPAddress,
BackendService = external.SelfLink,
LoadBalancingScheme = "EXTERNAL",
SourceIpRanges = new[]
{
"34.121.88.0/24",
"35.187.239.137",
},
}, new CustomResourceOptions
{
DependsOn =
{
externalForwardingRule,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Address;
import com.pulumi.gcp.compute.AddressArgs;
import com.pulumi.gcp.compute.RegionBackendService;
import com.pulumi.gcp.compute.RegionBackendServiceArgs;
import com.pulumi.gcp.compute.ForwardingRule;
import com.pulumi.gcp.compute.ForwardingRuleArgs;
import com.pulumi.resources.CustomResourceOptions;
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 basic = new Address("basic", AddressArgs.builder()
.name("website-ip")
.region("us-central1")
.build());
var external = new RegionBackendService("external", RegionBackendServiceArgs.builder()
.name("service-backend")
.region("us-central1")
.loadBalancingScheme("EXTERNAL")
.build());
var externalForwardingRule = new ForwardingRule("externalForwardingRule", ForwardingRuleArgs.builder()
.name("external-forwarding-rule")
.region("us-central1")
.ipAddress(basic.address())
.backendService(external.selfLink())
.loadBalancingScheme("EXTERNAL")
.build());
var steering = new ForwardingRule("steering", ForwardingRuleArgs.builder()
.name("steering-rule")
.region("us-central1")
.ipAddress(basic.address())
.backendService(external.selfLink())
.loadBalancingScheme("EXTERNAL")
.sourceIpRanges(
"34.121.88.0/24",
"35.187.239.137")
.build(), CustomResourceOptions.builder()
.dependsOn(externalForwardingRule)
.build());
}
}
resources:
steering:
type: gcp:compute:ForwardingRule
properties:
name: steering-rule
region: us-central1
ipAddress: ${basic.address}
backendService: ${external.selfLink}
loadBalancingScheme: EXTERNAL
sourceIpRanges:
- 34.121.88.0/24
- 35.187.239.137
options:
dependsOn:
- ${externalForwardingRule}
basic:
type: gcp:compute:Address
properties:
name: website-ip
region: us-central1
external:
type: gcp:compute:RegionBackendService
properties:
name: service-backend
region: us-central1
loadBalancingScheme: EXTERNAL
externalForwardingRule:
type: gcp:compute:ForwardingRule
name: external
properties:
name: external-forwarding-rule
region: us-central1
ipAddress: ${basic.address}
backendService: ${external.selfLink}
loadBalancingScheme: EXTERNAL
The sourceIpRanges property restricts which clients can use this forwarding rule. Traffic from the specified IP addresses or CIDR ranges routes to this rule’s backend, while other traffic uses the base forwarding rule. This requires a base rule with the same IP address and protocol but without source IP restrictions.
Beyond these examples
These snippets focus on specific forwarding rule features: external and internal load balancing schemes, Private Service Connect endpoints, and source IP-based traffic steering. They’re intentionally minimal rather than full load balancing deployments.
The examples may reference pre-existing infrastructure such as backend services, target pools, or service attachments, VPC networks and subnets, health checks and instance groups, and reserved IP addresses. 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)
- Service Directory registration
- Network tier selection (networkTier)
- Protocol-specific settings (ipProtocol, allPorts vs portRange)
- Global access controls (allowGlobalAccess)
- Labels and metadata
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 ForwardingRule resource reference for all available configuration options.
Let's configure GCP Networking Forwarding Rules
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Port Configuration & Conflicts
portRange to specify a range like “80-443”, ports to list up to 5 specific ports, or allPorts set to true to forward all ports. The allPorts option requires ipProtocol to be TCP, UDP, SCTP, or L3_DEFAULT.[ipAddress, ipProtocol] pair with overlapping port ranges. This applies to external forwarding rules globally and internal forwarding rules within the same VPC network.Load Balancing Schemes & Configuration
EXTERNAL (default), EXTERNAL_MANAGED, INTERNAL, INTERNAL_MANAGED, or an empty string for Private Service Connect use cases. The scheme determines whether the load balancer is internet-facing or internal, and whether it’s managed or passthrough.loadBalancingScheme to an empty string and configure target to point to a service attachment. You can optionally enable cross-region access with allowPscGlobalAccess.Immutability & Resource Constraints
ipAddress, ipProtocol, ipVersion, name, network, networkTier, portRange, region, subnetwork, backendService, target, and loadBalancingScheme. Changing these requires recreating the resource.sourceIpRanges. This feature only works with regional forwarding rules whose scheme is EXTERNAL.Cross-Region Access & Networking
allowGlobalAccess to true. This allows clients from all regions to access your internal load balancer, not just clients in the same region.allowGlobalAccess for internal load balancers with backendService or target fields. Use allowPscGlobalAccess specifically for Private Service Connect consumer forwarding rules to enable cross-region PSC endpoint access.sourceIpRanges with up to 64 IP addresses or CIDR ranges. The forwarding rule will only forward traffic when the source IP matches one of these ranges. This only works with regional EXTERNAL forwarding rules.IP Protocols & Advanced Features
L3_DEFAULT for protocol forwarding when you need to forward packets regardless of protocol. You must set allPorts to true and configure your backend service with UNSPECIFIED protocol. Note that L3_DEFAULT cannot attach to backend services with TCP or UDP protocols.isMirroringCollector can only be set to true for load balancers with loadBalancingScheme set to INTERNAL. This prevents mirroring loops.Using a different cloud?
Explore networking guides for other cloud providers: