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 or services to consumer projects. This guide focuses on three capabilities: connection acceptance policies, consumer access control via projects and networks, and tunneling configuration.

Service attachments reference existing ForwardingRules and require NAT subnets with purpose PRIVATE_SERVICE_CONNECT. 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

Service producers typically start by exposing an internal load balancer through Private Service Connect, allowing consumers to connect via private endpoints without traversing the public internet.

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 load balancer’s ForwardingRule. The natSubnets property specifies subnets used for NAT translation when consumers connect. Setting connectionPreference to “ACCEPT_AUTOMATIC” allows any consumer project to connect immediately without manual approval. The enableProxyProtocol property controls whether client TCP/IP information is preserved through the connection, and domainNames enables Cloud DNS integration for the service.

Control consumer access with project allowlists and denylists

When producers need fine-grained control over connections, they use manual acceptance with explicit project lists.

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 defines approved projects by projectIdOrNum, with each entry specifying a connectionLimit to cap concurrent connections. The consumerRejectLists property blocks specific projects entirely. This pattern gives producers precise control over who can consume their services.

Grant access by consumer VPC network

Instead of listing individual projects, producers can authorize entire VPC networks to connect.

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

The consumerAcceptLists property accepts networkUrl references instead of project IDs. This simplifies management when multiple projects share a common network infrastructure, as you authorize the network once rather than maintaining a per-project list.

Reconcile existing connections when policies change

By default, changes to accept and reject lists only affect pending connections. Connection reconciliation applies policy changes to already-accepted endpoints.

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

Setting reconcileConnections to true causes policy updates to affect both pending and accepted connections. For example, adding a project to consumerRejectLists will immediately disconnect any existing endpoints from that project, rather than leaving them in their current state.

Configure tunneling for cross-region connectivity

Service attachments can use tunneling to enable connectivity patterns beyond standard Private Service Connect.

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 controls routing behavior and encapsulation. Setting routingMode to “REGIONAL” keeps traffic within the region, while encapsulationProfile specifies the IP version used for tunneling. This configuration enables specialized connectivity scenarios that require custom routing or encapsulation.

Beyond these examples

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

The examples reference pre-existing infrastructure such as ForwardingRules (internal load balancers or global forwarding rules), NAT subnets with purpose PRIVATE_SERVICE_CONNECT, and VPC networks, backend services, and health checks. 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
  • Domain name configuration for Cloud DNS integration
  • NAT IP visibility (showNatIps)
  • Consumer endpoint monitoring (connectedEndpoints output)

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

Configuration & Setup
What properties can't I change after creating a service attachment?
Five properties are immutable: name, project, region, targetService, and domainNames. Changing any of these requires recreating the resource.
What are the naming requirements for a service attachment?
The name must be 1-63 characters, start with a lowercase letter, and match the regex a-z?. It can contain lowercase letters, digits, and dashes (but not as the last character).
What subnets do I need to provide for NAT?
Configure natSubnets with an array of subnet IDs that will be used for NAT in this service attachment. This is a required field.
Access Control
What's the difference between ACCEPT_AUTOMATIC and ACCEPT_MANUAL?
ACCEPT_AUTOMATIC automatically accepts connection requests, while ACCEPT_MANUAL requires explicit approval. Use consumerAcceptLists and consumerRejectLists to control access with ACCEPT_MANUAL.
Can I allow access by project or by network?
Yes, both options are available in consumerAcceptLists. Use projectIdOrNum for project-based access or networkUrl for network-based access, each with a connectionLimit.
Connection Management
What does reconcileConnections do to existing endpoints?
When reconcileConnections is true, changes to accept/reject lists affect existing ACCEPTED and REJECTED endpoints. When false, changes only affect PENDING endpoints, leaving existing connections untouched.
How do I set propagatedConnectionLimit to zero?
Set sendPropagatedConnectionLimitIfZero to true, then set propagatedConnectionLimit to 0. Without this flag, a zero value defaults to the API’s default of 250.
What's the default limit for propagated connections?
The default propagatedConnectionLimit is 250 connections per consumer project or network, depending on your connectionPreference setting.
Limitations & Constraints
How many domain names can I specify?
You can specify a maximum of 1 domain name in the domainNames array. The domain name is used for Cloud DNS integration with PSC endpoints.

Using a different cloud?

Explore networking guides for other cloud providers: