Skip to content

Private Services Access (PSA)

This guide explains the design and rationale behind Private Services Access (PSA) within our Google Cloud environment.

Tip

Looking for implementation steps? See our separate how-to guide to enable private IP for Cloud SQL.

What is Private Services Access?

Private Services Access is a networking connection between your VPC network and a network owned by Google (the "Service Producer" network).

By default, Google-managed services like Cloud SQL, Redis (Memorystore), and Filestore are hosted in isolated VPCs. Without PSA, you would have to connect to these services via public IP addresses. PSA creates a VPC Peering bridge, allowing your resources (such as Cloud Run via a VPC connector or GCE instances) to reach these services using internal, private IP addresses.

Benefits

  • Security: Traffic remains entirely within the Google Cloud backbone and never touches the public internet.
  • Performance: Lower latency and reduced network egress costs compared to public endpoints.
  • Simplicity: Services appear as if they are sitting on your own local network, making firewall management more intuitive.

Design aims in the Product Factory

When we integrated PSA into the gcp-product-factory, we settled on the following design aims:

  • Enable by default: Most new products require a database or cache; having the plumbing ready reduces setup friction for new teams.
  • Allow existing products to opt-in: Teams with existing products can choose to enable PSA when they are ready, without forcing changes on live systems. When switching to private IP on Cloud SQL, there is a downtime window while connections are migrated.
  • Support legacy infrastructure: Provide a toggle (enable_private_services_access) for older projects that may already have manual peering or overlapping IP ranges that conflict with factory defaults.

Resources created by the Factory

When the enable_private_services_access flag is set to true (the default), the Product Factory automatically provisions two primary resources:

  1. Global Internal IP Range (google_compute_global_address): A named IP block (typically a /16 range) reserved specifically for Google services. This range is not assigned to a subnet you can use for VMs; it is a "reservation" that Google carves up as you create database instances.

  2. Service Networking Connection (google_service_networking_connection): The actual peering configuration. This creates the "handshake" between your project's VPC and the servicenetworking.googleapis.com service producer.

Differences between PSA and standard peering

While PSA uses VPC Peering under the hood, there are key differences in how we manage it compared to standard project-to-project peering:

Feature Standard VPC Peering Private Services Access (PSA)
Visibility You see both sides of the peering in the console. You only see your side; the producer side is hidden.
IP Management You manage IPs on both ends of the link. You reserve a range; Google manages the sub-allocation.
Usage Connecting two of our VPCs together. Connecting our VPC to Google's managed services.

How to use PSA in your products

The Product Factory creates the "bridge," but individual services must be explicitly configured to use it.

Cloud SQL

When defining a Cloud SQL instance in Terraform, you must configure the ip_configuration to use the VPC network provided by the factory metadata. This ensures the database is injected into the peering bridge.

# Example snippet for a Cloud SQL resource
resource "google_sql_database_instance" "main" {
  settings {
    ip_configuration {
      ipv4_enabled        = false      # Disable public IP
      private_network     = "default"  # Use the PSA bridge
      authorized_networks = []
      ssl_mode            = "ENCRYPTED_ONLY"

      enable_private_path_for_google_cloud_services = true
    }
  }
}

Serverless VPC Access

To allow a Cloud Run service to reach a private Cloud SQL instance, you must also use a VPC Access Connector. The connector sits in your VPC and routes traffic across the PSA bridge to the database.

# Example snippet for a VPC Access Connector

module "webapp" {
  source  = "gitlab.developers.cam.ac.uk/uis/gcp-cloud-run-app/devops"
  version = "10.6.3"

  vpc_access = {
    egress = "PRIVATE_RANGES_ONLY"
    network_interfaces = {
      network    = "default"
      subnetwork = "default"
    }
  }
}

See also