Configure GCP Service Attachments

The gcp:compute/serviceAttachment:ServiceAttachment resource, part of the Pulumi GCP provider, defines a Private Service Connect service attachment that exposes internal load balancers to consumers through private endpoints. This guide focuses on three capabilities: connection acceptance policies, consumer access control via projects and networks, and tunneling configuration.

Service attachments reference existing internal load balancers and require NAT subnets with PRIVATE_SERVICE_CONNECT purpose. The examples are intentionally small. Combine them with your own load balancers, VPC networks, and access policies.

Expose an internal load balancer with automatic acceptance

Most Private Service Connect deployments start by exposing an internal load balancer, allowing consumers to connect via private endpoints without manual approval.

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

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",
    region: "us-west2",
    healthChecks: producerServiceHealthCheck.id,
});
const pscIlbNetwork = new gcp.compute.Network("psc_ilb_network", {
    name: "psc-ilb-network",
    autoCreateSubnetworks: false,
});
const pscIlbProducerSubnetwork = new gcp.compute.Subnetwork("psc_ilb_producer_subnetwork", {
    name: "psc-ilb-producer-subnetwork",
    region: "us-west2",
    network: pscIlbNetwork.id,
    ipCidrRange: "10.0.0.0/16",
});
const pscIlbTargetService = new gcp.compute.ForwardingRule("psc_ilb_target_service", {
    name: "producer-forwarding-rule",
    region: "us-west2",
    loadBalancingScheme: "INTERNAL",
    backendService: producerServiceBackend.id,
    allPorts: true,
    network: pscIlbNetwork.name,
    subnetwork: pscIlbProducerSubnetwork.name,
});
const pscIlbNat = new gcp.compute.Subnetwork("psc_ilb_nat", {
    name: "psc-ilb-nat",
    region: "us-west2",
    network: pscIlbNetwork.id,
    purpose: "PRIVATE_SERVICE_CONNECT",
    ipCidrRange: "10.1.0.0/16",
});
const pscIlbServiceAttachment = new gcp.compute.ServiceAttachment("psc_ilb_service_attachment", {
    name: "my-psc-ilb",
    region: "us-west2",
    description: "A service attachment configured with Terraform",
    domainNames: ["gcp.tfacc.hashicorptest.com."],
    enableProxyProtocol: true,
    connectionPreference: "ACCEPT_AUTOMATIC",
    natSubnets: [pscIlbNat.id],
    targetService: pscIlbTargetService.id,
});
const pscIlbConsumerAddress = new gcp.compute.Address("psc_ilb_consumer_address", {
    name: "psc-ilb-consumer-address",
    region: "us-west2",
    subnetwork: "default",
    addressType: "INTERNAL",
});
const pscIlbConsumer = new gcp.compute.ForwardingRule("psc_ilb_consumer", {
    name: "psc-ilb-consumer-forwarding-rule",
    region: "us-west2",
    target: pscIlbServiceAttachment.id,
    loadBalancingScheme: "",
    network: "default",
    ipAddress: pscIlbConsumerAddress.id,
});
import pulumi
import pulumi_gcp as gcp

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",
    region="us-west2",
    health_checks=producer_service_health_check.id)
psc_ilb_network = gcp.compute.Network("psc_ilb_network",
    name="psc-ilb-network",
    auto_create_subnetworks=False)
psc_ilb_producer_subnetwork = gcp.compute.Subnetwork("psc_ilb_producer_subnetwork",
    name="psc-ilb-producer-subnetwork",
    region="us-west2",
    network=psc_ilb_network.id,
    ip_cidr_range="10.0.0.0/16")
psc_ilb_target_service = gcp.compute.ForwardingRule("psc_ilb_target_service",
    name="producer-forwarding-rule",
    region="us-west2",
    load_balancing_scheme="INTERNAL",
    backend_service=producer_service_backend.id,
    all_ports=True,
    network=psc_ilb_network.name,
    subnetwork=psc_ilb_producer_subnetwork.name)
psc_ilb_nat = gcp.compute.Subnetwork("psc_ilb_nat",
    name="psc-ilb-nat",
    region="us-west2",
    network=psc_ilb_network.id,
    purpose="PRIVATE_SERVICE_CONNECT",
    ip_cidr_range="10.1.0.0/16")
psc_ilb_service_attachment = gcp.compute.ServiceAttachment("psc_ilb_service_attachment",
    name="my-psc-ilb",
    region="us-west2",
    description="A service attachment configured with Terraform",
    domain_names=["gcp.tfacc.hashicorptest.com."],
    enable_proxy_protocol=True,
    connection_preference="ACCEPT_AUTOMATIC",
    nat_subnets=[psc_ilb_nat.id],
    target_service=psc_ilb_target_service.id)
psc_ilb_consumer_address = gcp.compute.Address("psc_ilb_consumer_address",
    name="psc-ilb-consumer-address",
    region="us-west2",
    subnetwork="default",
    address_type="INTERNAL")
psc_ilb_consumer = gcp.compute.ForwardingRule("psc_ilb_consumer",
    name="psc-ilb-consumer-forwarding-rule",
    region="us-west2",
    target=psc_ilb_service_attachment.id,
    load_balancing_scheme="",
    network="default",
    ip_address=psc_ilb_consumer_address.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 {
		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"),
			Region:       pulumi.String("us-west2"),
			HealthChecks: producerServiceHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		pscIlbNetwork, err := compute.NewNetwork(ctx, "psc_ilb_network", &compute.NetworkArgs{
			Name:                  pulumi.String("psc-ilb-network"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		pscIlbProducerSubnetwork, err := compute.NewSubnetwork(ctx, "psc_ilb_producer_subnetwork", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-producer-subnetwork"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			IpCidrRange: pulumi.String("10.0.0.0/16"),
		})
		if err != nil {
			return err
		}
		pscIlbTargetService, err := compute.NewForwardingRule(ctx, "psc_ilb_target_service", &compute.ForwardingRuleArgs{
			Name:                pulumi.String("producer-forwarding-rule"),
			Region:              pulumi.String("us-west2"),
			LoadBalancingScheme: pulumi.String("INTERNAL"),
			BackendService:      producerServiceBackend.ID(),
			AllPorts:            pulumi.Bool(true),
			Network:             pscIlbNetwork.Name,
			Subnetwork:          pscIlbProducerSubnetwork.Name,
		})
		if err != nil {
			return err
		}
		pscIlbNat, err := compute.NewSubnetwork(ctx, "psc_ilb_nat", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-nat"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			Purpose:     pulumi.String("PRIVATE_SERVICE_CONNECT"),
			IpCidrRange: pulumi.String("10.1.0.0/16"),
		})
		if err != nil {
			return err
		}
		pscIlbServiceAttachment, err := compute.NewServiceAttachment(ctx, "psc_ilb_service_attachment", &compute.ServiceAttachmentArgs{
			Name:        pulumi.String("my-psc-ilb"),
			Region:      pulumi.String("us-west2"),
			Description: pulumi.String("A service attachment configured with Terraform"),
			DomainNames: pulumi.StringArray{
				pulumi.String("gcp.tfacc.hashicorptest.com."),
			},
			EnableProxyProtocol:  pulumi.Bool(true),
			ConnectionPreference: pulumi.String("ACCEPT_AUTOMATIC"),
			NatSubnets: pulumi.StringArray{
				pscIlbNat.ID(),
			},
			TargetService: pscIlbTargetService.ID(),
		})
		if err != nil {
			return err
		}
		pscIlbConsumerAddress, err := compute.NewAddress(ctx, "psc_ilb_consumer_address", &compute.AddressArgs{
			Name:        pulumi.String("psc-ilb-consumer-address"),
			Region:      pulumi.String("us-west2"),
			Subnetwork:  pulumi.String("default"),
			AddressType: pulumi.String("INTERNAL"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewForwardingRule(ctx, "psc_ilb_consumer", &compute.ForwardingRuleArgs{
			Name:                pulumi.String("psc-ilb-consumer-forwarding-rule"),
			Region:              pulumi.String("us-west2"),
			Target:              pscIlbServiceAttachment.ID(),
			LoadBalancingScheme: pulumi.String(""),
			Network:             pulumi.String("default"),
			IpAddress:           pscIlbConsumerAddress.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 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",
        Region = "us-west2",
        HealthChecks = producerServiceHealthCheck.Id,
    });

    var pscIlbNetwork = new Gcp.Compute.Network("psc_ilb_network", new()
    {
        Name = "psc-ilb-network",
        AutoCreateSubnetworks = false,
    });

    var pscIlbProducerSubnetwork = new Gcp.Compute.Subnetwork("psc_ilb_producer_subnetwork", new()
    {
        Name = "psc-ilb-producer-subnetwork",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        IpCidrRange = "10.0.0.0/16",
    });

    var pscIlbTargetService = new Gcp.Compute.ForwardingRule("psc_ilb_target_service", new()
    {
        Name = "producer-forwarding-rule",
        Region = "us-west2",
        LoadBalancingScheme = "INTERNAL",
        BackendService = producerServiceBackend.Id,
        AllPorts = true,
        Network = pscIlbNetwork.Name,
        Subnetwork = pscIlbProducerSubnetwork.Name,
    });

    var pscIlbNat = new Gcp.Compute.Subnetwork("psc_ilb_nat", new()
    {
        Name = "psc-ilb-nat",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        Purpose = "PRIVATE_SERVICE_CONNECT",
        IpCidrRange = "10.1.0.0/16",
    });

    var pscIlbServiceAttachment = new Gcp.Compute.ServiceAttachment("psc_ilb_service_attachment", new()
    {
        Name = "my-psc-ilb",
        Region = "us-west2",
        Description = "A service attachment configured with Terraform",
        DomainNames = new[]
        {
            "gcp.tfacc.hashicorptest.com.",
        },
        EnableProxyProtocol = true,
        ConnectionPreference = "ACCEPT_AUTOMATIC",
        NatSubnets = new[]
        {
            pscIlbNat.Id,
        },
        TargetService = pscIlbTargetService.Id,
    });

    var pscIlbConsumerAddress = new Gcp.Compute.Address("psc_ilb_consumer_address", new()
    {
        Name = "psc-ilb-consumer-address",
        Region = "us-west2",
        Subnetwork = "default",
        AddressType = "INTERNAL",
    });

    var pscIlbConsumer = new Gcp.Compute.ForwardingRule("psc_ilb_consumer", new()
    {
        Name = "psc-ilb-consumer-forwarding-rule",
        Region = "us-west2",
        Target = pscIlbServiceAttachment.Id,
        LoadBalancingScheme = "",
        Network = "default",
        IpAddress = pscIlbConsumerAddress.Id,
    });

});
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 com.pulumi.gcp.compute.ServiceAttachment;
import com.pulumi.gcp.compute.ServiceAttachmentArgs;
import com.pulumi.gcp.compute.Address;
import com.pulumi.gcp.compute.AddressArgs;
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 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")
            .region("us-west2")
            .healthChecks(producerServiceHealthCheck.id())
            .build());

        var pscIlbNetwork = new Network("pscIlbNetwork", NetworkArgs.builder()
            .name("psc-ilb-network")
            .autoCreateSubnetworks(false)
            .build());

        var pscIlbProducerSubnetwork = new Subnetwork("pscIlbProducerSubnetwork", SubnetworkArgs.builder()
            .name("psc-ilb-producer-subnetwork")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .ipCidrRange("10.0.0.0/16")
            .build());

        var pscIlbTargetService = new ForwardingRule("pscIlbTargetService", ForwardingRuleArgs.builder()
            .name("producer-forwarding-rule")
            .region("us-west2")
            .loadBalancingScheme("INTERNAL")
            .backendService(producerServiceBackend.id())
            .allPorts(true)
            .network(pscIlbNetwork.name())
            .subnetwork(pscIlbProducerSubnetwork.name())
            .build());

        var pscIlbNat = new Subnetwork("pscIlbNat", SubnetworkArgs.builder()
            .name("psc-ilb-nat")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .purpose("PRIVATE_SERVICE_CONNECT")
            .ipCidrRange("10.1.0.0/16")
            .build());

        var pscIlbServiceAttachment = new ServiceAttachment("pscIlbServiceAttachment", ServiceAttachmentArgs.builder()
            .name("my-psc-ilb")
            .region("us-west2")
            .description("A service attachment configured with Terraform")
            .domainNames("gcp.tfacc.hashicorptest.com.")
            .enableProxyProtocol(true)
            .connectionPreference("ACCEPT_AUTOMATIC")
            .natSubnets(pscIlbNat.id())
            .targetService(pscIlbTargetService.id())
            .build());

        var pscIlbConsumerAddress = new Address("pscIlbConsumerAddress", AddressArgs.builder()
            .name("psc-ilb-consumer-address")
            .region("us-west2")
            .subnetwork("default")
            .addressType("INTERNAL")
            .build());

        var pscIlbConsumer = new ForwardingRule("pscIlbConsumer", ForwardingRuleArgs.builder()
            .name("psc-ilb-consumer-forwarding-rule")
            .region("us-west2")
            .target(pscIlbServiceAttachment.id())
            .loadBalancingScheme("")
            .network("default")
            .ipAddress(pscIlbConsumerAddress.id())
            .build());

    }
}
resources:
  pscIlbServiceAttachment:
    type: gcp:compute:ServiceAttachment
    name: psc_ilb_service_attachment
    properties:
      name: my-psc-ilb
      region: us-west2
      description: A service attachment configured with Terraform
      domainNames:
        - gcp.tfacc.hashicorptest.com.
      enableProxyProtocol: true
      connectionPreference: ACCEPT_AUTOMATIC
      natSubnets:
        - ${pscIlbNat.id}
      targetService: ${pscIlbTargetService.id}
  pscIlbConsumerAddress:
    type: gcp:compute:Address
    name: psc_ilb_consumer_address
    properties:
      name: psc-ilb-consumer-address
      region: us-west2
      subnetwork: default
      addressType: INTERNAL
  pscIlbConsumer:
    type: gcp:compute:ForwardingRule
    name: psc_ilb_consumer
    properties:
      name: psc-ilb-consumer-forwarding-rule
      region: us-west2
      target: ${pscIlbServiceAttachment.id}
      loadBalancingScheme: ""
      network: default
      ipAddress: ${pscIlbConsumerAddress.id}
  pscIlbTargetService:
    type: gcp:compute:ForwardingRule
    name: psc_ilb_target_service
    properties:
      name: producer-forwarding-rule
      region: us-west2
      loadBalancingScheme: INTERNAL
      backendService: ${producerServiceBackend.id}
      allPorts: true
      network: ${pscIlbNetwork.name}
      subnetwork: ${pscIlbProducerSubnetwork.name}
  producerServiceBackend:
    type: gcp:compute:RegionBackendService
    name: producer_service_backend
    properties:
      name: producer-service
      region: us-west2
      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'
  pscIlbNetwork:
    type: gcp:compute:Network
    name: psc_ilb_network
    properties:
      name: psc-ilb-network
      autoCreateSubnetworks: false
  pscIlbProducerSubnetwork:
    type: gcp:compute:Subnetwork
    name: psc_ilb_producer_subnetwork
    properties:
      name: psc-ilb-producer-subnetwork
      region: us-west2
      network: ${pscIlbNetwork.id}
      ipCidrRange: 10.0.0.0/16
  pscIlbNat:
    type: gcp:compute:Subnetwork
    name: psc_ilb_nat
    properties:
      name: psc-ilb-nat
      region: us-west2
      network: ${pscIlbNetwork.id}
      purpose: PRIVATE_SERVICE_CONNECT
      ipCidrRange: 10.1.0.0/16

The targetService points to your internal ForwardingRule, which routes traffic to your backend service. The natSubnets property specifies subnets used for network address translation; these must have purpose set to PRIVATE_SERVICE_CONNECT. The connectionPreference of ACCEPT_AUTOMATIC allows any consumer to connect without manual approval. The enableProxyProtocol setting controls whether client TCP/IP address data is preserved through the proxy chain.

Control consumer access with project allowlists and denylists

When you need fine-grained control over which consumers can connect, configure explicit accept and reject lists based on project IDs.

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

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",
    region: "us-west2",
    healthChecks: producerServiceHealthCheck.id,
});
const pscIlbNetwork = new gcp.compute.Network("psc_ilb_network", {
    name: "psc-ilb-network",
    autoCreateSubnetworks: false,
});
const pscIlbProducerSubnetwork = new gcp.compute.Subnetwork("psc_ilb_producer_subnetwork", {
    name: "psc-ilb-producer-subnetwork",
    region: "us-west2",
    network: pscIlbNetwork.id,
    ipCidrRange: "10.0.0.0/16",
});
const pscIlbTargetService = new gcp.compute.ForwardingRule("psc_ilb_target_service", {
    name: "producer-forwarding-rule",
    region: "us-west2",
    loadBalancingScheme: "INTERNAL",
    backendService: producerServiceBackend.id,
    allPorts: true,
    network: pscIlbNetwork.name,
    subnetwork: pscIlbProducerSubnetwork.name,
});
const pscIlbNat = new gcp.compute.Subnetwork("psc_ilb_nat", {
    name: "psc-ilb-nat",
    region: "us-west2",
    network: pscIlbNetwork.id,
    purpose: "PRIVATE_SERVICE_CONNECT",
    ipCidrRange: "10.1.0.0/16",
});
const pscIlbServiceAttachment = new gcp.compute.ServiceAttachment("psc_ilb_service_attachment", {
    name: "my-psc-ilb",
    region: "us-west2",
    description: "A service attachment configured with Terraform",
    domainNames: ["gcp.tfacc.hashicorptest.com."],
    enableProxyProtocol: true,
    connectionPreference: "ACCEPT_MANUAL",
    natSubnets: [pscIlbNat.id],
    targetService: pscIlbTargetService.id,
    consumerRejectLists: [
        "673497134629",
        "482878270665",
    ],
    consumerAcceptLists: [{
        projectIdOrNum: "658859330310",
        connectionLimit: 4,
    }],
});
const pscIlbConsumerAddress = new gcp.compute.Address("psc_ilb_consumer_address", {
    name: "psc-ilb-consumer-address",
    region: "us-west2",
    subnetwork: "default",
    addressType: "INTERNAL",
});
const pscIlbConsumer = new gcp.compute.ForwardingRule("psc_ilb_consumer", {
    name: "psc-ilb-consumer-forwarding-rule",
    region: "us-west2",
    target: pscIlbServiceAttachment.id,
    loadBalancingScheme: "",
    network: "default",
    ipAddress: pscIlbConsumerAddress.id,
});
import pulumi
import pulumi_gcp as gcp

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",
    region="us-west2",
    health_checks=producer_service_health_check.id)
psc_ilb_network = gcp.compute.Network("psc_ilb_network",
    name="psc-ilb-network",
    auto_create_subnetworks=False)
psc_ilb_producer_subnetwork = gcp.compute.Subnetwork("psc_ilb_producer_subnetwork",
    name="psc-ilb-producer-subnetwork",
    region="us-west2",
    network=psc_ilb_network.id,
    ip_cidr_range="10.0.0.0/16")
psc_ilb_target_service = gcp.compute.ForwardingRule("psc_ilb_target_service",
    name="producer-forwarding-rule",
    region="us-west2",
    load_balancing_scheme="INTERNAL",
    backend_service=producer_service_backend.id,
    all_ports=True,
    network=psc_ilb_network.name,
    subnetwork=psc_ilb_producer_subnetwork.name)
psc_ilb_nat = gcp.compute.Subnetwork("psc_ilb_nat",
    name="psc-ilb-nat",
    region="us-west2",
    network=psc_ilb_network.id,
    purpose="PRIVATE_SERVICE_CONNECT",
    ip_cidr_range="10.1.0.0/16")
psc_ilb_service_attachment = gcp.compute.ServiceAttachment("psc_ilb_service_attachment",
    name="my-psc-ilb",
    region="us-west2",
    description="A service attachment configured with Terraform",
    domain_names=["gcp.tfacc.hashicorptest.com."],
    enable_proxy_protocol=True,
    connection_preference="ACCEPT_MANUAL",
    nat_subnets=[psc_ilb_nat.id],
    target_service=psc_ilb_target_service.id,
    consumer_reject_lists=[
        "673497134629",
        "482878270665",
    ],
    consumer_accept_lists=[{
        "project_id_or_num": "658859330310",
        "connection_limit": 4,
    }])
psc_ilb_consumer_address = gcp.compute.Address("psc_ilb_consumer_address",
    name="psc-ilb-consumer-address",
    region="us-west2",
    subnetwork="default",
    address_type="INTERNAL")
psc_ilb_consumer = gcp.compute.ForwardingRule("psc_ilb_consumer",
    name="psc-ilb-consumer-forwarding-rule",
    region="us-west2",
    target=psc_ilb_service_attachment.id,
    load_balancing_scheme="",
    network="default",
    ip_address=psc_ilb_consumer_address.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 {
		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"),
			Region:       pulumi.String("us-west2"),
			HealthChecks: producerServiceHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		pscIlbNetwork, err := compute.NewNetwork(ctx, "psc_ilb_network", &compute.NetworkArgs{
			Name:                  pulumi.String("psc-ilb-network"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		pscIlbProducerSubnetwork, err := compute.NewSubnetwork(ctx, "psc_ilb_producer_subnetwork", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-producer-subnetwork"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			IpCidrRange: pulumi.String("10.0.0.0/16"),
		})
		if err != nil {
			return err
		}
		pscIlbTargetService, err := compute.NewForwardingRule(ctx, "psc_ilb_target_service", &compute.ForwardingRuleArgs{
			Name:                pulumi.String("producer-forwarding-rule"),
			Region:              pulumi.String("us-west2"),
			LoadBalancingScheme: pulumi.String("INTERNAL"),
			BackendService:      producerServiceBackend.ID(),
			AllPorts:            pulumi.Bool(true),
			Network:             pscIlbNetwork.Name,
			Subnetwork:          pscIlbProducerSubnetwork.Name,
		})
		if err != nil {
			return err
		}
		pscIlbNat, err := compute.NewSubnetwork(ctx, "psc_ilb_nat", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-nat"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			Purpose:     pulumi.String("PRIVATE_SERVICE_CONNECT"),
			IpCidrRange: pulumi.String("10.1.0.0/16"),
		})
		if err != nil {
			return err
		}
		pscIlbServiceAttachment, err := compute.NewServiceAttachment(ctx, "psc_ilb_service_attachment", &compute.ServiceAttachmentArgs{
			Name:        pulumi.String("my-psc-ilb"),
			Region:      pulumi.String("us-west2"),
			Description: pulumi.String("A service attachment configured with Terraform"),
			DomainNames: pulumi.StringArray{
				pulumi.String("gcp.tfacc.hashicorptest.com."),
			},
			EnableProxyProtocol:  pulumi.Bool(true),
			ConnectionPreference: pulumi.String("ACCEPT_MANUAL"),
			NatSubnets: pulumi.StringArray{
				pscIlbNat.ID(),
			},
			TargetService: pscIlbTargetService.ID(),
			ConsumerRejectLists: pulumi.StringArray{
				pulumi.String("673497134629"),
				pulumi.String("482878270665"),
			},
			ConsumerAcceptLists: compute.ServiceAttachmentConsumerAcceptListArray{
				&compute.ServiceAttachmentConsumerAcceptListArgs{
					ProjectIdOrNum:  pulumi.String("658859330310"),
					ConnectionLimit: pulumi.Int(4),
				},
			},
		})
		if err != nil {
			return err
		}
		pscIlbConsumerAddress, err := compute.NewAddress(ctx, "psc_ilb_consumer_address", &compute.AddressArgs{
			Name:        pulumi.String("psc-ilb-consumer-address"),
			Region:      pulumi.String("us-west2"),
			Subnetwork:  pulumi.String("default"),
			AddressType: pulumi.String("INTERNAL"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewForwardingRule(ctx, "psc_ilb_consumer", &compute.ForwardingRuleArgs{
			Name:                pulumi.String("psc-ilb-consumer-forwarding-rule"),
			Region:              pulumi.String("us-west2"),
			Target:              pscIlbServiceAttachment.ID(),
			LoadBalancingScheme: pulumi.String(""),
			Network:             pulumi.String("default"),
			IpAddress:           pscIlbConsumerAddress.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 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",
        Region = "us-west2",
        HealthChecks = producerServiceHealthCheck.Id,
    });

    var pscIlbNetwork = new Gcp.Compute.Network("psc_ilb_network", new()
    {
        Name = "psc-ilb-network",
        AutoCreateSubnetworks = false,
    });

    var pscIlbProducerSubnetwork = new Gcp.Compute.Subnetwork("psc_ilb_producer_subnetwork", new()
    {
        Name = "psc-ilb-producer-subnetwork",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        IpCidrRange = "10.0.0.0/16",
    });

    var pscIlbTargetService = new Gcp.Compute.ForwardingRule("psc_ilb_target_service", new()
    {
        Name = "producer-forwarding-rule",
        Region = "us-west2",
        LoadBalancingScheme = "INTERNAL",
        BackendService = producerServiceBackend.Id,
        AllPorts = true,
        Network = pscIlbNetwork.Name,
        Subnetwork = pscIlbProducerSubnetwork.Name,
    });

    var pscIlbNat = new Gcp.Compute.Subnetwork("psc_ilb_nat", new()
    {
        Name = "psc-ilb-nat",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        Purpose = "PRIVATE_SERVICE_CONNECT",
        IpCidrRange = "10.1.0.0/16",
    });

    var pscIlbServiceAttachment = new Gcp.Compute.ServiceAttachment("psc_ilb_service_attachment", new()
    {
        Name = "my-psc-ilb",
        Region = "us-west2",
        Description = "A service attachment configured with Terraform",
        DomainNames = new[]
        {
            "gcp.tfacc.hashicorptest.com.",
        },
        EnableProxyProtocol = true,
        ConnectionPreference = "ACCEPT_MANUAL",
        NatSubnets = new[]
        {
            pscIlbNat.Id,
        },
        TargetService = pscIlbTargetService.Id,
        ConsumerRejectLists = new[]
        {
            "673497134629",
            "482878270665",
        },
        ConsumerAcceptLists = new[]
        {
            new Gcp.Compute.Inputs.ServiceAttachmentConsumerAcceptListArgs
            {
                ProjectIdOrNum = "658859330310",
                ConnectionLimit = 4,
            },
        },
    });

    var pscIlbConsumerAddress = new Gcp.Compute.Address("psc_ilb_consumer_address", new()
    {
        Name = "psc-ilb-consumer-address",
        Region = "us-west2",
        Subnetwork = "default",
        AddressType = "INTERNAL",
    });

    var pscIlbConsumer = new Gcp.Compute.ForwardingRule("psc_ilb_consumer", new()
    {
        Name = "psc-ilb-consumer-forwarding-rule",
        Region = "us-west2",
        Target = pscIlbServiceAttachment.Id,
        LoadBalancingScheme = "",
        Network = "default",
        IpAddress = pscIlbConsumerAddress.Id,
    });

});
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 com.pulumi.gcp.compute.ServiceAttachment;
import com.pulumi.gcp.compute.ServiceAttachmentArgs;
import com.pulumi.gcp.compute.inputs.ServiceAttachmentConsumerAcceptListArgs;
import com.pulumi.gcp.compute.Address;
import com.pulumi.gcp.compute.AddressArgs;
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 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")
            .region("us-west2")
            .healthChecks(producerServiceHealthCheck.id())
            .build());

        var pscIlbNetwork = new Network("pscIlbNetwork", NetworkArgs.builder()
            .name("psc-ilb-network")
            .autoCreateSubnetworks(false)
            .build());

        var pscIlbProducerSubnetwork = new Subnetwork("pscIlbProducerSubnetwork", SubnetworkArgs.builder()
            .name("psc-ilb-producer-subnetwork")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .ipCidrRange("10.0.0.0/16")
            .build());

        var pscIlbTargetService = new ForwardingRule("pscIlbTargetService", ForwardingRuleArgs.builder()
            .name("producer-forwarding-rule")
            .region("us-west2")
            .loadBalancingScheme("INTERNAL")
            .backendService(producerServiceBackend.id())
            .allPorts(true)
            .network(pscIlbNetwork.name())
            .subnetwork(pscIlbProducerSubnetwork.name())
            .build());

        var pscIlbNat = new Subnetwork("pscIlbNat", SubnetworkArgs.builder()
            .name("psc-ilb-nat")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .purpose("PRIVATE_SERVICE_CONNECT")
            .ipCidrRange("10.1.0.0/16")
            .build());

        var pscIlbServiceAttachment = new ServiceAttachment("pscIlbServiceAttachment", ServiceAttachmentArgs.builder()
            .name("my-psc-ilb")
            .region("us-west2")
            .description("A service attachment configured with Terraform")
            .domainNames("gcp.tfacc.hashicorptest.com.")
            .enableProxyProtocol(true)
            .connectionPreference("ACCEPT_MANUAL")
            .natSubnets(pscIlbNat.id())
            .targetService(pscIlbTargetService.id())
            .consumerRejectLists(            
                "673497134629",
                "482878270665")
            .consumerAcceptLists(ServiceAttachmentConsumerAcceptListArgs.builder()
                .projectIdOrNum("658859330310")
                .connectionLimit(4)
                .build())
            .build());

        var pscIlbConsumerAddress = new Address("pscIlbConsumerAddress", AddressArgs.builder()
            .name("psc-ilb-consumer-address")
            .region("us-west2")
            .subnetwork("default")
            .addressType("INTERNAL")
            .build());

        var pscIlbConsumer = new ForwardingRule("pscIlbConsumer", ForwardingRuleArgs.builder()
            .name("psc-ilb-consumer-forwarding-rule")
            .region("us-west2")
            .target(pscIlbServiceAttachment.id())
            .loadBalancingScheme("")
            .network("default")
            .ipAddress(pscIlbConsumerAddress.id())
            .build());

    }
}
resources:
  pscIlbServiceAttachment:
    type: gcp:compute:ServiceAttachment
    name: psc_ilb_service_attachment
    properties:
      name: my-psc-ilb
      region: us-west2
      description: A service attachment configured with Terraform
      domainNames:
        - gcp.tfacc.hashicorptest.com.
      enableProxyProtocol: true
      connectionPreference: ACCEPT_MANUAL
      natSubnets:
        - ${pscIlbNat.id}
      targetService: ${pscIlbTargetService.id}
      consumerRejectLists:
        - '673497134629'
        - '482878270665'
      consumerAcceptLists:
        - projectIdOrNum: '658859330310'
          connectionLimit: 4
  pscIlbConsumerAddress:
    type: gcp:compute:Address
    name: psc_ilb_consumer_address
    properties:
      name: psc-ilb-consumer-address
      region: us-west2
      subnetwork: default
      addressType: INTERNAL
  pscIlbConsumer:
    type: gcp:compute:ForwardingRule
    name: psc_ilb_consumer
    properties:
      name: psc-ilb-consumer-forwarding-rule
      region: us-west2
      target: ${pscIlbServiceAttachment.id}
      loadBalancingScheme: ""
      network: default
      ipAddress: ${pscIlbConsumerAddress.id}
  pscIlbTargetService:
    type: gcp:compute:ForwardingRule
    name: psc_ilb_target_service
    properties:
      name: producer-forwarding-rule
      region: us-west2
      loadBalancingScheme: INTERNAL
      backendService: ${producerServiceBackend.id}
      allPorts: true
      network: ${pscIlbNetwork.name}
      subnetwork: ${pscIlbProducerSubnetwork.name}
  producerServiceBackend:
    type: gcp:compute:RegionBackendService
    name: producer_service_backend
    properties:
      name: producer-service
      region: us-west2
      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'
  pscIlbNetwork:
    type: gcp:compute:Network
    name: psc_ilb_network
    properties:
      name: psc-ilb-network
      autoCreateSubnetworks: false
  pscIlbProducerSubnetwork:
    type: gcp:compute:Subnetwork
    name: psc_ilb_producer_subnetwork
    properties:
      name: psc-ilb-producer-subnetwork
      region: us-west2
      network: ${pscIlbNetwork.id}
      ipCidrRange: 10.0.0.0/16
  pscIlbNat:
    type: gcp:compute:Subnetwork
    name: psc_ilb_nat
    properties:
      name: psc-ilb-nat
      region: us-west2
      network: ${pscIlbNetwork.id}
      purpose: PRIVATE_SERVICE_CONNECT
      ipCidrRange: 10.1.0.0/16

With connectionPreference set to ACCEPT_MANUAL, connections require explicit approval. The consumerAcceptLists property specifies which projects can connect, with projectIdOrNum identifying each project and connectionLimit capping the number of endpoints per project. The consumerRejectLists property blocks specific projects entirely. This configuration gives you precise control over who accesses your service.

Grant access by consumer network instead of project

Some deployments authorize consumers by VPC network rather than project ID, allowing connections from specific networks regardless of project boundaries.

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

const pscIlbConsumerNetwork = new gcp.compute.Network("psc_ilb_consumer_network", {
    name: "psc-ilb-consumer-network",
    autoCreateSubnetworks: false,
});
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",
    region: "us-west2",
    healthChecks: producerServiceHealthCheck.id,
});
const pscIlbNetwork = new gcp.compute.Network("psc_ilb_network", {
    name: "psc-ilb-network",
    autoCreateSubnetworks: false,
});
const pscIlbProducerSubnetwork = new gcp.compute.Subnetwork("psc_ilb_producer_subnetwork", {
    name: "psc-ilb-producer-subnetwork",
    region: "us-west2",
    network: pscIlbNetwork.id,
    ipCidrRange: "10.0.0.0/16",
});
const pscIlbTargetService = new gcp.compute.ForwardingRule("psc_ilb_target_service", {
    name: "producer-forwarding-rule",
    region: "us-west2",
    loadBalancingScheme: "INTERNAL",
    backendService: producerServiceBackend.id,
    allPorts: true,
    network: pscIlbNetwork.name,
    subnetwork: pscIlbProducerSubnetwork.name,
});
const pscIlbNat = new gcp.compute.Subnetwork("psc_ilb_nat", {
    name: "psc-ilb-nat",
    region: "us-west2",
    network: pscIlbNetwork.id,
    purpose: "PRIVATE_SERVICE_CONNECT",
    ipCidrRange: "10.1.0.0/16",
});
const pscIlbServiceAttachment = new gcp.compute.ServiceAttachment("psc_ilb_service_attachment", {
    name: "my-psc-ilb",
    region: "us-west2",
    description: "A service attachment configured with Terraform",
    enableProxyProtocol: false,
    connectionPreference: "ACCEPT_MANUAL",
    natSubnets: [pscIlbNat.id],
    targetService: pscIlbTargetService.id,
    consumerAcceptLists: [{
        networkUrl: pscIlbConsumerNetwork.selfLink,
        connectionLimit: 1,
    }],
});
const pscIlbConsumerSubnetwork = new gcp.compute.Subnetwork("psc_ilb_consumer_subnetwork", {
    name: "psc-ilb-consumer-network",
    ipCidrRange: "10.0.0.0/16",
    region: "us-west2",
    network: pscIlbConsumerNetwork.id,
});
const pscIlbConsumerAddress = new gcp.compute.Address("psc_ilb_consumer_address", {
    name: "psc-ilb-consumer-address",
    region: "us-west2",
    subnetwork: pscIlbConsumerSubnetwork.id,
    addressType: "INTERNAL",
});
const pscIlbConsumer = new gcp.compute.ForwardingRule("psc_ilb_consumer", {
    name: "psc-ilb-consumer-forwarding-rule",
    region: "us-west2",
    target: pscIlbServiceAttachment.id,
    loadBalancingScheme: "",
    network: pscIlbConsumerNetwork.id,
    subnetwork: pscIlbConsumerSubnetwork.id,
    ipAddress: pscIlbConsumerAddress.id,
});
import pulumi
import pulumi_gcp as gcp

psc_ilb_consumer_network = gcp.compute.Network("psc_ilb_consumer_network",
    name="psc-ilb-consumer-network",
    auto_create_subnetworks=False)
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",
    region="us-west2",
    health_checks=producer_service_health_check.id)
psc_ilb_network = gcp.compute.Network("psc_ilb_network",
    name="psc-ilb-network",
    auto_create_subnetworks=False)
psc_ilb_producer_subnetwork = gcp.compute.Subnetwork("psc_ilb_producer_subnetwork",
    name="psc-ilb-producer-subnetwork",
    region="us-west2",
    network=psc_ilb_network.id,
    ip_cidr_range="10.0.0.0/16")
psc_ilb_target_service = gcp.compute.ForwardingRule("psc_ilb_target_service",
    name="producer-forwarding-rule",
    region="us-west2",
    load_balancing_scheme="INTERNAL",
    backend_service=producer_service_backend.id,
    all_ports=True,
    network=psc_ilb_network.name,
    subnetwork=psc_ilb_producer_subnetwork.name)
psc_ilb_nat = gcp.compute.Subnetwork("psc_ilb_nat",
    name="psc-ilb-nat",
    region="us-west2",
    network=psc_ilb_network.id,
    purpose="PRIVATE_SERVICE_CONNECT",
    ip_cidr_range="10.1.0.0/16")
psc_ilb_service_attachment = gcp.compute.ServiceAttachment("psc_ilb_service_attachment",
    name="my-psc-ilb",
    region="us-west2",
    description="A service attachment configured with Terraform",
    enable_proxy_protocol=False,
    connection_preference="ACCEPT_MANUAL",
    nat_subnets=[psc_ilb_nat.id],
    target_service=psc_ilb_target_service.id,
    consumer_accept_lists=[{
        "network_url": psc_ilb_consumer_network.self_link,
        "connection_limit": 1,
    }])
psc_ilb_consumer_subnetwork = gcp.compute.Subnetwork("psc_ilb_consumer_subnetwork",
    name="psc-ilb-consumer-network",
    ip_cidr_range="10.0.0.0/16",
    region="us-west2",
    network=psc_ilb_consumer_network.id)
psc_ilb_consumer_address = gcp.compute.Address("psc_ilb_consumer_address",
    name="psc-ilb-consumer-address",
    region="us-west2",
    subnetwork=psc_ilb_consumer_subnetwork.id,
    address_type="INTERNAL")
psc_ilb_consumer = gcp.compute.ForwardingRule("psc_ilb_consumer",
    name="psc-ilb-consumer-forwarding-rule",
    region="us-west2",
    target=psc_ilb_service_attachment.id,
    load_balancing_scheme="",
    network=psc_ilb_consumer_network.id,
    subnetwork=psc_ilb_consumer_subnetwork.id,
    ip_address=psc_ilb_consumer_address.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 {
		pscIlbConsumerNetwork, err := compute.NewNetwork(ctx, "psc_ilb_consumer_network", &compute.NetworkArgs{
			Name:                  pulumi.String("psc-ilb-consumer-network"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		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"),
			Region:       pulumi.String("us-west2"),
			HealthChecks: producerServiceHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		pscIlbNetwork, err := compute.NewNetwork(ctx, "psc_ilb_network", &compute.NetworkArgs{
			Name:                  pulumi.String("psc-ilb-network"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		pscIlbProducerSubnetwork, err := compute.NewSubnetwork(ctx, "psc_ilb_producer_subnetwork", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-producer-subnetwork"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			IpCidrRange: pulumi.String("10.0.0.0/16"),
		})
		if err != nil {
			return err
		}
		pscIlbTargetService, err := compute.NewForwardingRule(ctx, "psc_ilb_target_service", &compute.ForwardingRuleArgs{
			Name:                pulumi.String("producer-forwarding-rule"),
			Region:              pulumi.String("us-west2"),
			LoadBalancingScheme: pulumi.String("INTERNAL"),
			BackendService:      producerServiceBackend.ID(),
			AllPorts:            pulumi.Bool(true),
			Network:             pscIlbNetwork.Name,
			Subnetwork:          pscIlbProducerSubnetwork.Name,
		})
		if err != nil {
			return err
		}
		pscIlbNat, err := compute.NewSubnetwork(ctx, "psc_ilb_nat", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-nat"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			Purpose:     pulumi.String("PRIVATE_SERVICE_CONNECT"),
			IpCidrRange: pulumi.String("10.1.0.0/16"),
		})
		if err != nil {
			return err
		}
		pscIlbServiceAttachment, err := compute.NewServiceAttachment(ctx, "psc_ilb_service_attachment", &compute.ServiceAttachmentArgs{
			Name:                 pulumi.String("my-psc-ilb"),
			Region:               pulumi.String("us-west2"),
			Description:          pulumi.String("A service attachment configured with Terraform"),
			EnableProxyProtocol:  pulumi.Bool(false),
			ConnectionPreference: pulumi.String("ACCEPT_MANUAL"),
			NatSubnets: pulumi.StringArray{
				pscIlbNat.ID(),
			},
			TargetService: pscIlbTargetService.ID(),
			ConsumerAcceptLists: compute.ServiceAttachmentConsumerAcceptListArray{
				&compute.ServiceAttachmentConsumerAcceptListArgs{
					NetworkUrl:      pscIlbConsumerNetwork.SelfLink,
					ConnectionLimit: pulumi.Int(1),
				},
			},
		})
		if err != nil {
			return err
		}
		pscIlbConsumerSubnetwork, err := compute.NewSubnetwork(ctx, "psc_ilb_consumer_subnetwork", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-consumer-network"),
			IpCidrRange: pulumi.String("10.0.0.0/16"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbConsumerNetwork.ID(),
		})
		if err != nil {
			return err
		}
		pscIlbConsumerAddress, err := compute.NewAddress(ctx, "psc_ilb_consumer_address", &compute.AddressArgs{
			Name:        pulumi.String("psc-ilb-consumer-address"),
			Region:      pulumi.String("us-west2"),
			Subnetwork:  pscIlbConsumerSubnetwork.ID(),
			AddressType: pulumi.String("INTERNAL"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewForwardingRule(ctx, "psc_ilb_consumer", &compute.ForwardingRuleArgs{
			Name:                pulumi.String("psc-ilb-consumer-forwarding-rule"),
			Region:              pulumi.String("us-west2"),
			Target:              pscIlbServiceAttachment.ID(),
			LoadBalancingScheme: pulumi.String(""),
			Network:             pscIlbConsumerNetwork.ID(),
			Subnetwork:          pscIlbConsumerSubnetwork.ID(),
			IpAddress:           pscIlbConsumerAddress.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 pscIlbConsumerNetwork = new Gcp.Compute.Network("psc_ilb_consumer_network", new()
    {
        Name = "psc-ilb-consumer-network",
        AutoCreateSubnetworks = false,
    });

    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",
        Region = "us-west2",
        HealthChecks = producerServiceHealthCheck.Id,
    });

    var pscIlbNetwork = new Gcp.Compute.Network("psc_ilb_network", new()
    {
        Name = "psc-ilb-network",
        AutoCreateSubnetworks = false,
    });

    var pscIlbProducerSubnetwork = new Gcp.Compute.Subnetwork("psc_ilb_producer_subnetwork", new()
    {
        Name = "psc-ilb-producer-subnetwork",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        IpCidrRange = "10.0.0.0/16",
    });

    var pscIlbTargetService = new Gcp.Compute.ForwardingRule("psc_ilb_target_service", new()
    {
        Name = "producer-forwarding-rule",
        Region = "us-west2",
        LoadBalancingScheme = "INTERNAL",
        BackendService = producerServiceBackend.Id,
        AllPorts = true,
        Network = pscIlbNetwork.Name,
        Subnetwork = pscIlbProducerSubnetwork.Name,
    });

    var pscIlbNat = new Gcp.Compute.Subnetwork("psc_ilb_nat", new()
    {
        Name = "psc-ilb-nat",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        Purpose = "PRIVATE_SERVICE_CONNECT",
        IpCidrRange = "10.1.0.0/16",
    });

    var pscIlbServiceAttachment = new Gcp.Compute.ServiceAttachment("psc_ilb_service_attachment", new()
    {
        Name = "my-psc-ilb",
        Region = "us-west2",
        Description = "A service attachment configured with Terraform",
        EnableProxyProtocol = false,
        ConnectionPreference = "ACCEPT_MANUAL",
        NatSubnets = new[]
        {
            pscIlbNat.Id,
        },
        TargetService = pscIlbTargetService.Id,
        ConsumerAcceptLists = new[]
        {
            new Gcp.Compute.Inputs.ServiceAttachmentConsumerAcceptListArgs
            {
                NetworkUrl = pscIlbConsumerNetwork.SelfLink,
                ConnectionLimit = 1,
            },
        },
    });

    var pscIlbConsumerSubnetwork = new Gcp.Compute.Subnetwork("psc_ilb_consumer_subnetwork", new()
    {
        Name = "psc-ilb-consumer-network",
        IpCidrRange = "10.0.0.0/16",
        Region = "us-west2",
        Network = pscIlbConsumerNetwork.Id,
    });

    var pscIlbConsumerAddress = new Gcp.Compute.Address("psc_ilb_consumer_address", new()
    {
        Name = "psc-ilb-consumer-address",
        Region = "us-west2",
        Subnetwork = pscIlbConsumerSubnetwork.Id,
        AddressType = "INTERNAL",
    });

    var pscIlbConsumer = new Gcp.Compute.ForwardingRule("psc_ilb_consumer", new()
    {
        Name = "psc-ilb-consumer-forwarding-rule",
        Region = "us-west2",
        Target = pscIlbServiceAttachment.Id,
        LoadBalancingScheme = "",
        Network = pscIlbConsumerNetwork.Id,
        Subnetwork = pscIlbConsumerSubnetwork.Id,
        IpAddress = pscIlbConsumerAddress.Id,
    });

});
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.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.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
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 com.pulumi.gcp.compute.inputs.ServiceAttachmentConsumerAcceptListArgs;
import com.pulumi.gcp.compute.Address;
import com.pulumi.gcp.compute.AddressArgs;
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 pscIlbConsumerNetwork = new Network("pscIlbConsumerNetwork", NetworkArgs.builder()
            .name("psc-ilb-consumer-network")
            .autoCreateSubnetworks(false)
            .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")
            .region("us-west2")
            .healthChecks(producerServiceHealthCheck.id())
            .build());

        var pscIlbNetwork = new Network("pscIlbNetwork", NetworkArgs.builder()
            .name("psc-ilb-network")
            .autoCreateSubnetworks(false)
            .build());

        var pscIlbProducerSubnetwork = new Subnetwork("pscIlbProducerSubnetwork", SubnetworkArgs.builder()
            .name("psc-ilb-producer-subnetwork")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .ipCidrRange("10.0.0.0/16")
            .build());

        var pscIlbTargetService = new ForwardingRule("pscIlbTargetService", ForwardingRuleArgs.builder()
            .name("producer-forwarding-rule")
            .region("us-west2")
            .loadBalancingScheme("INTERNAL")
            .backendService(producerServiceBackend.id())
            .allPorts(true)
            .network(pscIlbNetwork.name())
            .subnetwork(pscIlbProducerSubnetwork.name())
            .build());

        var pscIlbNat = new Subnetwork("pscIlbNat", SubnetworkArgs.builder()
            .name("psc-ilb-nat")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .purpose("PRIVATE_SERVICE_CONNECT")
            .ipCidrRange("10.1.0.0/16")
            .build());

        var pscIlbServiceAttachment = new ServiceAttachment("pscIlbServiceAttachment", ServiceAttachmentArgs.builder()
            .name("my-psc-ilb")
            .region("us-west2")
            .description("A service attachment configured with Terraform")
            .enableProxyProtocol(false)
            .connectionPreference("ACCEPT_MANUAL")
            .natSubnets(pscIlbNat.id())
            .targetService(pscIlbTargetService.id())
            .consumerAcceptLists(ServiceAttachmentConsumerAcceptListArgs.builder()
                .networkUrl(pscIlbConsumerNetwork.selfLink())
                .connectionLimit(1)
                .build())
            .build());

        var pscIlbConsumerSubnetwork = new Subnetwork("pscIlbConsumerSubnetwork", SubnetworkArgs.builder()
            .name("psc-ilb-consumer-network")
            .ipCidrRange("10.0.0.0/16")
            .region("us-west2")
            .network(pscIlbConsumerNetwork.id())
            .build());

        var pscIlbConsumerAddress = new Address("pscIlbConsumerAddress", AddressArgs.builder()
            .name("psc-ilb-consumer-address")
            .region("us-west2")
            .subnetwork(pscIlbConsumerSubnetwork.id())
            .addressType("INTERNAL")
            .build());

        var pscIlbConsumer = new ForwardingRule("pscIlbConsumer", ForwardingRuleArgs.builder()
            .name("psc-ilb-consumer-forwarding-rule")
            .region("us-west2")
            .target(pscIlbServiceAttachment.id())
            .loadBalancingScheme("")
            .network(pscIlbConsumerNetwork.id())
            .subnetwork(pscIlbConsumerSubnetwork.id())
            .ipAddress(pscIlbConsumerAddress.id())
            .build());

    }
}
resources:
  pscIlbServiceAttachment:
    type: gcp:compute:ServiceAttachment
    name: psc_ilb_service_attachment
    properties:
      name: my-psc-ilb
      region: us-west2
      description: A service attachment configured with Terraform
      enableProxyProtocol: false
      connectionPreference: ACCEPT_MANUAL
      natSubnets:
        - ${pscIlbNat.id}
      targetService: ${pscIlbTargetService.id}
      consumerAcceptLists:
        - networkUrl: ${pscIlbConsumerNetwork.selfLink}
          connectionLimit: 1
  pscIlbConsumerNetwork:
    type: gcp:compute:Network
    name: psc_ilb_consumer_network
    properties:
      name: psc-ilb-consumer-network
      autoCreateSubnetworks: false
  pscIlbConsumerSubnetwork:
    type: gcp:compute:Subnetwork
    name: psc_ilb_consumer_subnetwork
    properties:
      name: psc-ilb-consumer-network
      ipCidrRange: 10.0.0.0/16
      region: us-west2
      network: ${pscIlbConsumerNetwork.id}
  pscIlbConsumerAddress:
    type: gcp:compute:Address
    name: psc_ilb_consumer_address
    properties:
      name: psc-ilb-consumer-address
      region: us-west2
      subnetwork: ${pscIlbConsumerSubnetwork.id}
      addressType: INTERNAL
  pscIlbConsumer:
    type: gcp:compute:ForwardingRule
    name: psc_ilb_consumer
    properties:
      name: psc-ilb-consumer-forwarding-rule
      region: us-west2
      target: ${pscIlbServiceAttachment.id}
      loadBalancingScheme: ""
      network: ${pscIlbConsumerNetwork.id}
      subnetwork: ${pscIlbConsumerSubnetwork.id}
      ipAddress: ${pscIlbConsumerAddress.id}
  pscIlbTargetService:
    type: gcp:compute:ForwardingRule
    name: psc_ilb_target_service
    properties:
      name: producer-forwarding-rule
      region: us-west2
      loadBalancingScheme: INTERNAL
      backendService: ${producerServiceBackend.id}
      allPorts: true
      network: ${pscIlbNetwork.name}
      subnetwork: ${pscIlbProducerSubnetwork.name}
  producerServiceBackend:
    type: gcp:compute:RegionBackendService
    name: producer_service_backend
    properties:
      name: producer-service
      region: us-west2
      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'
  pscIlbNetwork:
    type: gcp:compute:Network
    name: psc_ilb_network
    properties:
      name: psc-ilb-network
      autoCreateSubnetworks: false
  pscIlbProducerSubnetwork:
    type: gcp:compute:Subnetwork
    name: psc_ilb_producer_subnetwork
    properties:
      name: psc-ilb-producer-subnetwork
      region: us-west2
      network: ${pscIlbNetwork.id}
      ipCidrRange: 10.0.0.0/16
  pscIlbNat:
    type: gcp:compute:Subnetwork
    name: psc_ilb_nat
    properties:
      name: psc-ilb-nat
      region: us-west2
      network: ${pscIlbNetwork.id}
      purpose: PRIVATE_SERVICE_CONNECT
      ipCidrRange: 10.1.0.0/16

Instead of projectIdOrNum, the consumerAcceptLists uses networkUrl to reference a consumer VPC network. This approach works well when you want to grant access based on network topology rather than organizational structure. The connectionLimit still applies per network.

Prevent automatic disconnection of existing endpoints

By default, changes to accept/reject lists can disconnect existing endpoints. Disabling reconciliation preserves existing connections while only affecting new requests.

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

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",
    region: "us-west2",
    healthChecks: producerServiceHealthCheck.id,
});
const pscIlbNetwork = new gcp.compute.Network("psc_ilb_network", {
    name: "psc-ilb-network",
    autoCreateSubnetworks: false,
});
const pscIlbProducerSubnetwork = new gcp.compute.Subnetwork("psc_ilb_producer_subnetwork", {
    name: "psc-ilb-producer-subnetwork",
    region: "us-west2",
    network: pscIlbNetwork.id,
    ipCidrRange: "10.0.0.0/16",
});
const pscIlbTargetService = new gcp.compute.ForwardingRule("psc_ilb_target_service", {
    name: "producer-forwarding-rule",
    region: "us-west2",
    loadBalancingScheme: "INTERNAL",
    backendService: producerServiceBackend.id,
    allPorts: true,
    network: pscIlbNetwork.name,
    subnetwork: pscIlbProducerSubnetwork.name,
});
const pscIlbNat = new gcp.compute.Subnetwork("psc_ilb_nat", {
    name: "psc-ilb-nat",
    region: "us-west2",
    network: pscIlbNetwork.id,
    purpose: "PRIVATE_SERVICE_CONNECT",
    ipCidrRange: "10.1.0.0/16",
});
const pscIlbServiceAttachment = new gcp.compute.ServiceAttachment("psc_ilb_service_attachment", {
    name: "my-psc-ilb",
    region: "us-west2",
    description: "A service attachment configured with Terraform",
    domainNames: ["gcp.tfacc.hashicorptest.com."],
    enableProxyProtocol: true,
    connectionPreference: "ACCEPT_MANUAL",
    natSubnets: [pscIlbNat.id],
    targetService: pscIlbTargetService.id,
    consumerRejectLists: [
        "673497134629",
        "482878270665",
    ],
    consumerAcceptLists: [{
        projectIdOrNum: "658859330310",
        connectionLimit: 4,
    }],
    reconcileConnections: false,
});
import pulumi
import pulumi_gcp as gcp

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",
    region="us-west2",
    health_checks=producer_service_health_check.id)
psc_ilb_network = gcp.compute.Network("psc_ilb_network",
    name="psc-ilb-network",
    auto_create_subnetworks=False)
psc_ilb_producer_subnetwork = gcp.compute.Subnetwork("psc_ilb_producer_subnetwork",
    name="psc-ilb-producer-subnetwork",
    region="us-west2",
    network=psc_ilb_network.id,
    ip_cidr_range="10.0.0.0/16")
psc_ilb_target_service = gcp.compute.ForwardingRule("psc_ilb_target_service",
    name="producer-forwarding-rule",
    region="us-west2",
    load_balancing_scheme="INTERNAL",
    backend_service=producer_service_backend.id,
    all_ports=True,
    network=psc_ilb_network.name,
    subnetwork=psc_ilb_producer_subnetwork.name)
psc_ilb_nat = gcp.compute.Subnetwork("psc_ilb_nat",
    name="psc-ilb-nat",
    region="us-west2",
    network=psc_ilb_network.id,
    purpose="PRIVATE_SERVICE_CONNECT",
    ip_cidr_range="10.1.0.0/16")
psc_ilb_service_attachment = gcp.compute.ServiceAttachment("psc_ilb_service_attachment",
    name="my-psc-ilb",
    region="us-west2",
    description="A service attachment configured with Terraform",
    domain_names=["gcp.tfacc.hashicorptest.com."],
    enable_proxy_protocol=True,
    connection_preference="ACCEPT_MANUAL",
    nat_subnets=[psc_ilb_nat.id],
    target_service=psc_ilb_target_service.id,
    consumer_reject_lists=[
        "673497134629",
        "482878270665",
    ],
    consumer_accept_lists=[{
        "project_id_or_num": "658859330310",
        "connection_limit": 4,
    }],
    reconcile_connections=False)
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 {
		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"),
			Region:       pulumi.String("us-west2"),
			HealthChecks: producerServiceHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		pscIlbNetwork, err := compute.NewNetwork(ctx, "psc_ilb_network", &compute.NetworkArgs{
			Name:                  pulumi.String("psc-ilb-network"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		pscIlbProducerSubnetwork, err := compute.NewSubnetwork(ctx, "psc_ilb_producer_subnetwork", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-producer-subnetwork"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			IpCidrRange: pulumi.String("10.0.0.0/16"),
		})
		if err != nil {
			return err
		}
		pscIlbTargetService, err := compute.NewForwardingRule(ctx, "psc_ilb_target_service", &compute.ForwardingRuleArgs{
			Name:                pulumi.String("producer-forwarding-rule"),
			Region:              pulumi.String("us-west2"),
			LoadBalancingScheme: pulumi.String("INTERNAL"),
			BackendService:      producerServiceBackend.ID(),
			AllPorts:            pulumi.Bool(true),
			Network:             pscIlbNetwork.Name,
			Subnetwork:          pscIlbProducerSubnetwork.Name,
		})
		if err != nil {
			return err
		}
		pscIlbNat, err := compute.NewSubnetwork(ctx, "psc_ilb_nat", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-nat"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			Purpose:     pulumi.String("PRIVATE_SERVICE_CONNECT"),
			IpCidrRange: pulumi.String("10.1.0.0/16"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewServiceAttachment(ctx, "psc_ilb_service_attachment", &compute.ServiceAttachmentArgs{
			Name:        pulumi.String("my-psc-ilb"),
			Region:      pulumi.String("us-west2"),
			Description: pulumi.String("A service attachment configured with Terraform"),
			DomainNames: pulumi.StringArray{
				pulumi.String("gcp.tfacc.hashicorptest.com."),
			},
			EnableProxyProtocol:  pulumi.Bool(true),
			ConnectionPreference: pulumi.String("ACCEPT_MANUAL"),
			NatSubnets: pulumi.StringArray{
				pscIlbNat.ID(),
			},
			TargetService: pscIlbTargetService.ID(),
			ConsumerRejectLists: pulumi.StringArray{
				pulumi.String("673497134629"),
				pulumi.String("482878270665"),
			},
			ConsumerAcceptLists: compute.ServiceAttachmentConsumerAcceptListArray{
				&compute.ServiceAttachmentConsumerAcceptListArgs{
					ProjectIdOrNum:  pulumi.String("658859330310"),
					ConnectionLimit: pulumi.Int(4),
				},
			},
			ReconcileConnections: pulumi.Bool(false),
		})
		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 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",
        Region = "us-west2",
        HealthChecks = producerServiceHealthCheck.Id,
    });

    var pscIlbNetwork = new Gcp.Compute.Network("psc_ilb_network", new()
    {
        Name = "psc-ilb-network",
        AutoCreateSubnetworks = false,
    });

    var pscIlbProducerSubnetwork = new Gcp.Compute.Subnetwork("psc_ilb_producer_subnetwork", new()
    {
        Name = "psc-ilb-producer-subnetwork",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        IpCidrRange = "10.0.0.0/16",
    });

    var pscIlbTargetService = new Gcp.Compute.ForwardingRule("psc_ilb_target_service", new()
    {
        Name = "producer-forwarding-rule",
        Region = "us-west2",
        LoadBalancingScheme = "INTERNAL",
        BackendService = producerServiceBackend.Id,
        AllPorts = true,
        Network = pscIlbNetwork.Name,
        Subnetwork = pscIlbProducerSubnetwork.Name,
    });

    var pscIlbNat = new Gcp.Compute.Subnetwork("psc_ilb_nat", new()
    {
        Name = "psc-ilb-nat",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        Purpose = "PRIVATE_SERVICE_CONNECT",
        IpCidrRange = "10.1.0.0/16",
    });

    var pscIlbServiceAttachment = new Gcp.Compute.ServiceAttachment("psc_ilb_service_attachment", new()
    {
        Name = "my-psc-ilb",
        Region = "us-west2",
        Description = "A service attachment configured with Terraform",
        DomainNames = new[]
        {
            "gcp.tfacc.hashicorptest.com.",
        },
        EnableProxyProtocol = true,
        ConnectionPreference = "ACCEPT_MANUAL",
        NatSubnets = new[]
        {
            pscIlbNat.Id,
        },
        TargetService = pscIlbTargetService.Id,
        ConsumerRejectLists = new[]
        {
            "673497134629",
            "482878270665",
        },
        ConsumerAcceptLists = new[]
        {
            new Gcp.Compute.Inputs.ServiceAttachmentConsumerAcceptListArgs
            {
                ProjectIdOrNum = "658859330310",
                ConnectionLimit = 4,
            },
        },
        ReconcileConnections = false,
    });

});
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 com.pulumi.gcp.compute.ServiceAttachment;
import com.pulumi.gcp.compute.ServiceAttachmentArgs;
import com.pulumi.gcp.compute.inputs.ServiceAttachmentConsumerAcceptListArgs;
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 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")
            .region("us-west2")
            .healthChecks(producerServiceHealthCheck.id())
            .build());

        var pscIlbNetwork = new Network("pscIlbNetwork", NetworkArgs.builder()
            .name("psc-ilb-network")
            .autoCreateSubnetworks(false)
            .build());

        var pscIlbProducerSubnetwork = new Subnetwork("pscIlbProducerSubnetwork", SubnetworkArgs.builder()
            .name("psc-ilb-producer-subnetwork")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .ipCidrRange("10.0.0.0/16")
            .build());

        var pscIlbTargetService = new ForwardingRule("pscIlbTargetService", ForwardingRuleArgs.builder()
            .name("producer-forwarding-rule")
            .region("us-west2")
            .loadBalancingScheme("INTERNAL")
            .backendService(producerServiceBackend.id())
            .allPorts(true)
            .network(pscIlbNetwork.name())
            .subnetwork(pscIlbProducerSubnetwork.name())
            .build());

        var pscIlbNat = new Subnetwork("pscIlbNat", SubnetworkArgs.builder()
            .name("psc-ilb-nat")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .purpose("PRIVATE_SERVICE_CONNECT")
            .ipCidrRange("10.1.0.0/16")
            .build());

        var pscIlbServiceAttachment = new ServiceAttachment("pscIlbServiceAttachment", ServiceAttachmentArgs.builder()
            .name("my-psc-ilb")
            .region("us-west2")
            .description("A service attachment configured with Terraform")
            .domainNames("gcp.tfacc.hashicorptest.com.")
            .enableProxyProtocol(true)
            .connectionPreference("ACCEPT_MANUAL")
            .natSubnets(pscIlbNat.id())
            .targetService(pscIlbTargetService.id())
            .consumerRejectLists(            
                "673497134629",
                "482878270665")
            .consumerAcceptLists(ServiceAttachmentConsumerAcceptListArgs.builder()
                .projectIdOrNum("658859330310")
                .connectionLimit(4)
                .build())
            .reconcileConnections(false)
            .build());

    }
}
resources:
  pscIlbServiceAttachment:
    type: gcp:compute:ServiceAttachment
    name: psc_ilb_service_attachment
    properties:
      name: my-psc-ilb
      region: us-west2
      description: A service attachment configured with Terraform
      domainNames:
        - gcp.tfacc.hashicorptest.com.
      enableProxyProtocol: true
      connectionPreference: ACCEPT_MANUAL
      natSubnets:
        - ${pscIlbNat.id}
      targetService: ${pscIlbTargetService.id}
      consumerRejectLists:
        - '673497134629'
        - '482878270665'
      consumerAcceptLists:
        - projectIdOrNum: '658859330310'
          connectionLimit: 4
      reconcileConnections: false
  pscIlbTargetService:
    type: gcp:compute:ForwardingRule
    name: psc_ilb_target_service
    properties:
      name: producer-forwarding-rule
      region: us-west2
      loadBalancingScheme: INTERNAL
      backendService: ${producerServiceBackend.id}
      allPorts: true
      network: ${pscIlbNetwork.name}
      subnetwork: ${pscIlbProducerSubnetwork.name}
  producerServiceBackend:
    type: gcp:compute:RegionBackendService
    name: producer_service_backend
    properties:
      name: producer-service
      region: us-west2
      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'
  pscIlbNetwork:
    type: gcp:compute:Network
    name: psc_ilb_network
    properties:
      name: psc-ilb-network
      autoCreateSubnetworks: false
  pscIlbProducerSubnetwork:
    type: gcp:compute:Subnetwork
    name: psc_ilb_producer_subnetwork
    properties:
      name: psc-ilb-producer-subnetwork
      region: us-west2
      network: ${pscIlbNetwork.id}
      ipCidrRange: 10.0.0.0/16
  pscIlbNat:
    type: gcp:compute:Subnetwork
    name: psc_ilb_nat
    properties:
      name: psc-ilb-nat
      region: us-west2
      network: ${pscIlbNetwork.id}
      purpose: PRIVATE_SERVICE_CONNECT
      ipCidrRange: 10.1.0.0/16

The reconcileConnections property controls whether policy changes affect existing ACCEPTED or REJECTED endpoints. When set to false, only PENDING endpoints are affected by accept/reject list updates. Existing connections remain stable even if you add their project to the reject list. This prevents disruption when updating access policies.

Configure tunneling for cross-region connectivity

Service attachments can use tunneling to enable cross-region Private Service Connect connections with specific routing and encapsulation settings.

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

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",
    region: "us-west2",
    healthChecks: producerServiceHealthCheck.id,
});
const pscIlbNetwork = new gcp.compute.Network("psc_ilb_network", {
    name: "psc-ilb-network",
    autoCreateSubnetworks: false,
});
const pscIlbProducerSubnetwork = new gcp.compute.Subnetwork("psc_ilb_producer_subnetwork", {
    name: "psc-ilb-producer-subnetwork",
    region: "us-west2",
    network: pscIlbNetwork.id,
    ipCidrRange: "10.0.0.0/16",
});
const pscIlbTargetService = new gcp.compute.ForwardingRule("psc_ilb_target_service", {
    name: "producer-forwarding-rule",
    region: "us-west2",
    loadBalancingScheme: "INTERNAL",
    backendService: producerServiceBackend.id,
    allPorts: true,
    network: pscIlbNetwork.name,
    subnetwork: pscIlbProducerSubnetwork.name,
});
const pscIlbNat = new gcp.compute.Subnetwork("psc_ilb_nat", {
    name: "psc-ilb-nat",
    region: "us-west2",
    network: pscIlbNetwork.id,
    purpose: "PRIVATE_SERVICE_CONNECT",
    ipCidrRange: "10.1.0.0/16",
});
const pscIlbServiceAttachment = new gcp.compute.ServiceAttachment("psc_ilb_service_attachment", {
    name: "my-psc-ilb",
    region: "us-west2",
    description: "A service attachment configured with tunneling",
    enableProxyProtocol: false,
    connectionPreference: "ACCEPT_AUTOMATIC",
    natSubnets: [pscIlbNat.id],
    targetService: pscIlbTargetService.id,
    tunnelingConfig: {
        routingMode: "REGIONAL",
        encapsulationProfile: "IPV4",
    },
});
import pulumi
import pulumi_gcp as gcp

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",
    region="us-west2",
    health_checks=producer_service_health_check.id)
psc_ilb_network = gcp.compute.Network("psc_ilb_network",
    name="psc-ilb-network",
    auto_create_subnetworks=False)
psc_ilb_producer_subnetwork = gcp.compute.Subnetwork("psc_ilb_producer_subnetwork",
    name="psc-ilb-producer-subnetwork",
    region="us-west2",
    network=psc_ilb_network.id,
    ip_cidr_range="10.0.0.0/16")
psc_ilb_target_service = gcp.compute.ForwardingRule("psc_ilb_target_service",
    name="producer-forwarding-rule",
    region="us-west2",
    load_balancing_scheme="INTERNAL",
    backend_service=producer_service_backend.id,
    all_ports=True,
    network=psc_ilb_network.name,
    subnetwork=psc_ilb_producer_subnetwork.name)
psc_ilb_nat = gcp.compute.Subnetwork("psc_ilb_nat",
    name="psc-ilb-nat",
    region="us-west2",
    network=psc_ilb_network.id,
    purpose="PRIVATE_SERVICE_CONNECT",
    ip_cidr_range="10.1.0.0/16")
psc_ilb_service_attachment = gcp.compute.ServiceAttachment("psc_ilb_service_attachment",
    name="my-psc-ilb",
    region="us-west2",
    description="A service attachment configured with tunneling",
    enable_proxy_protocol=False,
    connection_preference="ACCEPT_AUTOMATIC",
    nat_subnets=[psc_ilb_nat.id],
    target_service=psc_ilb_target_service.id,
    tunneling_config={
        "routing_mode": "REGIONAL",
        "encapsulation_profile": "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 {
		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"),
			Region:       pulumi.String("us-west2"),
			HealthChecks: producerServiceHealthCheck.ID(),
		})
		if err != nil {
			return err
		}
		pscIlbNetwork, err := compute.NewNetwork(ctx, "psc_ilb_network", &compute.NetworkArgs{
			Name:                  pulumi.String("psc-ilb-network"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		pscIlbProducerSubnetwork, err := compute.NewSubnetwork(ctx, "psc_ilb_producer_subnetwork", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-producer-subnetwork"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			IpCidrRange: pulumi.String("10.0.0.0/16"),
		})
		if err != nil {
			return err
		}
		pscIlbTargetService, err := compute.NewForwardingRule(ctx, "psc_ilb_target_service", &compute.ForwardingRuleArgs{
			Name:                pulumi.String("producer-forwarding-rule"),
			Region:              pulumi.String("us-west2"),
			LoadBalancingScheme: pulumi.String("INTERNAL"),
			BackendService:      producerServiceBackend.ID(),
			AllPorts:            pulumi.Bool(true),
			Network:             pscIlbNetwork.Name,
			Subnetwork:          pscIlbProducerSubnetwork.Name,
		})
		if err != nil {
			return err
		}
		pscIlbNat, err := compute.NewSubnetwork(ctx, "psc_ilb_nat", &compute.SubnetworkArgs{
			Name:        pulumi.String("psc-ilb-nat"),
			Region:      pulumi.String("us-west2"),
			Network:     pscIlbNetwork.ID(),
			Purpose:     pulumi.String("PRIVATE_SERVICE_CONNECT"),
			IpCidrRange: pulumi.String("10.1.0.0/16"),
		})
		if err != nil {
			return err
		}
		_, err = compute.NewServiceAttachment(ctx, "psc_ilb_service_attachment", &compute.ServiceAttachmentArgs{
			Name:                 pulumi.String("my-psc-ilb"),
			Region:               pulumi.String("us-west2"),
			Description:          pulumi.String("A service attachment configured with tunneling"),
			EnableProxyProtocol:  pulumi.Bool(false),
			ConnectionPreference: pulumi.String("ACCEPT_AUTOMATIC"),
			NatSubnets: pulumi.StringArray{
				pscIlbNat.ID(),
			},
			TargetService: pscIlbTargetService.ID(),
			TunnelingConfig: &compute.ServiceAttachmentTunnelingConfigArgs{
				RoutingMode:          pulumi.String("REGIONAL"),
				EncapsulationProfile: 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 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",
        Region = "us-west2",
        HealthChecks = producerServiceHealthCheck.Id,
    });

    var pscIlbNetwork = new Gcp.Compute.Network("psc_ilb_network", new()
    {
        Name = "psc-ilb-network",
        AutoCreateSubnetworks = false,
    });

    var pscIlbProducerSubnetwork = new Gcp.Compute.Subnetwork("psc_ilb_producer_subnetwork", new()
    {
        Name = "psc-ilb-producer-subnetwork",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        IpCidrRange = "10.0.0.0/16",
    });

    var pscIlbTargetService = new Gcp.Compute.ForwardingRule("psc_ilb_target_service", new()
    {
        Name = "producer-forwarding-rule",
        Region = "us-west2",
        LoadBalancingScheme = "INTERNAL",
        BackendService = producerServiceBackend.Id,
        AllPorts = true,
        Network = pscIlbNetwork.Name,
        Subnetwork = pscIlbProducerSubnetwork.Name,
    });

    var pscIlbNat = new Gcp.Compute.Subnetwork("psc_ilb_nat", new()
    {
        Name = "psc-ilb-nat",
        Region = "us-west2",
        Network = pscIlbNetwork.Id,
        Purpose = "PRIVATE_SERVICE_CONNECT",
        IpCidrRange = "10.1.0.0/16",
    });

    var pscIlbServiceAttachment = new Gcp.Compute.ServiceAttachment("psc_ilb_service_attachment", new()
    {
        Name = "my-psc-ilb",
        Region = "us-west2",
        Description = "A service attachment configured with tunneling",
        EnableProxyProtocol = false,
        ConnectionPreference = "ACCEPT_AUTOMATIC",
        NatSubnets = new[]
        {
            pscIlbNat.Id,
        },
        TargetService = pscIlbTargetService.Id,
        TunnelingConfig = new Gcp.Compute.Inputs.ServiceAttachmentTunnelingConfigArgs
        {
            RoutingMode = "REGIONAL",
            EncapsulationProfile = "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 com.pulumi.gcp.compute.ServiceAttachment;
import com.pulumi.gcp.compute.ServiceAttachmentArgs;
import com.pulumi.gcp.compute.inputs.ServiceAttachmentTunnelingConfigArgs;
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 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")
            .region("us-west2")
            .healthChecks(producerServiceHealthCheck.id())
            .build());

        var pscIlbNetwork = new Network("pscIlbNetwork", NetworkArgs.builder()
            .name("psc-ilb-network")
            .autoCreateSubnetworks(false)
            .build());

        var pscIlbProducerSubnetwork = new Subnetwork("pscIlbProducerSubnetwork", SubnetworkArgs.builder()
            .name("psc-ilb-producer-subnetwork")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .ipCidrRange("10.0.0.0/16")
            .build());

        var pscIlbTargetService = new ForwardingRule("pscIlbTargetService", ForwardingRuleArgs.builder()
            .name("producer-forwarding-rule")
            .region("us-west2")
            .loadBalancingScheme("INTERNAL")
            .backendService(producerServiceBackend.id())
            .allPorts(true)
            .network(pscIlbNetwork.name())
            .subnetwork(pscIlbProducerSubnetwork.name())
            .build());

        var pscIlbNat = new Subnetwork("pscIlbNat", SubnetworkArgs.builder()
            .name("psc-ilb-nat")
            .region("us-west2")
            .network(pscIlbNetwork.id())
            .purpose("PRIVATE_SERVICE_CONNECT")
            .ipCidrRange("10.1.0.0/16")
            .build());

        var pscIlbServiceAttachment = new ServiceAttachment("pscIlbServiceAttachment", ServiceAttachmentArgs.builder()
            .name("my-psc-ilb")
            .region("us-west2")
            .description("A service attachment configured with tunneling")
            .enableProxyProtocol(false)
            .connectionPreference("ACCEPT_AUTOMATIC")
            .natSubnets(pscIlbNat.id())
            .targetService(pscIlbTargetService.id())
            .tunnelingConfig(ServiceAttachmentTunnelingConfigArgs.builder()
                .routingMode("REGIONAL")
                .encapsulationProfile("IPV4")
                .build())
            .build());

    }
}
resources:
  pscIlbServiceAttachment:
    type: gcp:compute:ServiceAttachment
    name: psc_ilb_service_attachment
    properties:
      name: my-psc-ilb
      region: us-west2
      description: A service attachment configured with tunneling
      enableProxyProtocol: false
      connectionPreference: ACCEPT_AUTOMATIC
      natSubnets:
        - ${pscIlbNat.id}
      targetService: ${pscIlbTargetService.id}
      tunnelingConfig:
        routingMode: REGIONAL
        encapsulationProfile: IPV4
  pscIlbTargetService:
    type: gcp:compute:ForwardingRule
    name: psc_ilb_target_service
    properties:
      name: producer-forwarding-rule
      region: us-west2
      loadBalancingScheme: INTERNAL
      backendService: ${producerServiceBackend.id}
      allPorts: true
      network: ${pscIlbNetwork.name}
      subnetwork: ${pscIlbProducerSubnetwork.name}
  producerServiceBackend:
    type: gcp:compute:RegionBackendService
    name: producer_service_backend
    properties:
      name: producer-service
      region: us-west2
      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'
  pscIlbNetwork:
    type: gcp:compute:Network
    name: psc_ilb_network
    properties:
      name: psc-ilb-network
      autoCreateSubnetworks: false
  pscIlbProducerSubnetwork:
    type: gcp:compute:Subnetwork
    name: psc_ilb_producer_subnetwork
    properties:
      name: psc-ilb-producer-subnetwork
      region: us-west2
      network: ${pscIlbNetwork.id}
      ipCidrRange: 10.0.0.0/16
  pscIlbNat:
    type: gcp:compute:Subnetwork
    name: psc_ilb_nat
    properties:
      name: psc-ilb-nat
      region: us-west2
      network: ${pscIlbNetwork.id}
      purpose: PRIVATE_SERVICE_CONNECT
      ipCidrRange: 10.1.0.0/16

The tunnelingConfig property enables cross-region connectivity. The routingMode of REGIONAL keeps traffic within the region when possible, while encapsulationProfile specifies IPv4 encapsulation for the tunnel. This configuration is typically used when consumers need to access your service from different regions.

Beyond these examples

These snippets focus on specific service attachment features: connection acceptance policies, consumer access control via projects and networks, and tunneling configuration. They’re intentionally minimal rather than full Private Service Connect deployments.

The examples reference pre-existing infrastructure such as internal load balancers (ForwardingRule, BackendService), VPC networks and subnets (including NAT subnets with PRIVATE_SERVICE_CONNECT purpose), and health checks for backend services. They focus on configuring the service attachment rather than provisioning the underlying load balancer infrastructure.

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

  • Propagated connection limits for Network Connectivity Center (propagatedConnectionLimit)
  • Domain name configuration for Cloud DNS integration (domainNames)
  • Proxy protocol settings (enableProxyProtocol variations)
  • Connection reconciliation behavior (reconcileConnections in different scenarios)

These omissions are intentional: the goal is to illustrate how each service attachment feature is wired, not provide drop-in Private Service Connect modules. See the ServiceAttachment resource reference for all available configuration options.

Let's configure GCP Service Attachments

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Connection Management
What's the difference between ACCEPT_AUTOMATIC and ACCEPT_MANUAL connection preferences?
ACCEPT_AUTOMATIC automatically accepts all connection requests, while ACCEPT_MANUAL requires you to explicitly approve connections using consumerAcceptLists.
How do I control which projects can connect to my service attachment?
Set connectionPreference to ACCEPT_MANUAL and use consumerAcceptLists to specify allowed projects with projectIdOrNum and connectionLimit. You can also block projects using consumerRejectLists.
Can I allow connections from specific networks instead of entire projects?
Yes, use networkUrl instead of projectIdOrNum in consumerAcceptLists to allow connections from specific VPC networks.
What happens to existing connections when I change the accept or reject lists?
If reconcileConnections is true, changes affect both PENDING and existing ACCEPTED/REJECTED endpoints (e.g., an ACCEPTED endpoint moves to REJECTED if its project is added to the reject list). If false, only PENDING endpoints are affected.
Configuration & Limits
What are the naming requirements for a service attachment?
The name must be 1-63 characters long, start with a lowercase letter, and match the regex [a-z][-a-z0-9]*[a-z0-9] (lowercase letters, digits, and dashes, with no trailing dash).
What's the default propagated connection limit and how do I change it?
The default propagatedConnectionLimit is 250 connections per consumer project or network. To explicitly set it to zero, you must also set sendPropagatedConnectionLimitIfZero to true; otherwise, the provider uses the API’s default.
What properties can't be changed after creating a service attachment?
The name, domainNames, region, and project properties are immutable and cannot be modified after creation.
How many domain names can I configure for Cloud DNS integration?
You can specify a maximum of 1 domain name in the domainNames array for Cloud DNS integration with PSC endpoints.
Known Issues
Why isn't the showNatIps field working?
The showNatIps field is temporarily non-functional due to an underlying API issue. Any value you provide will be ignored until the issue is resolved, expected around 2026-03.
Advanced Features
What does enableProxyProtocol do?
When enableProxyProtocol is true, it enables the proxy protocol to supply client TCP/IP address data in TCP connections that traverse proxies to destination servers.
How do I configure tunneling for my service attachment?
Use the tunnelingConfig property with routingMode (e.g., REGIONAL) and encapsulationProfile (e.g., IPV4) to enable tunneling.

Using a different cloud?

Explore networking guides for other cloud providers: