Running Cloud Run services privately inside a VPC means your serverless containers can talk to other resources within your Virtual Private Cloud (VPC) network without exposing them to the public internet.
Here’s a Cloud Run service deployed with VPC Network Access, configured to connect to a private PostgreSQL instance in Cloud SQL:
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: private-service
spec:
template:
spec:
containers:
- image: gcr.io/my-project/my-private-app:latest
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "10.0.1.5" # Private IP of Cloud SQL instance
- name: DB_USER
value: "myuser"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
# VPC Network Access configuration
vpcAccess:
connector: projects/my-project/locations/us-central1/connectors/my-vpc-connector
egress: ALL
The core problem this solves is secure communication between your serverless workloads and your private backend infrastructure. Traditionally, if you wanted your Cloud Run service to access a database or another service running on a private IP within your VPC, you’d either have to expose that backend to the internet (a security risk) or find a way to bridge the gap. VPC Network Access provides that bridge.
Internally, Cloud Run uses a managed VPC Network Access connector. This connector is essentially a small, always-on VM instance (or a set of instances for high availability) deployed within your VPC. When your Cloud Run service is configured for VPC Network Access, its outbound traffic is routed through this connector. The connector then acts as a gateway, allowing your service to send traffic directly into your VPC network using private IP addresses.
The egress field is crucial. ALL means all outbound traffic from your Cloud Run service will be routed through the VPC connector. This is the most common and straightforward setting, ensuring all communication to private resources goes via your VPC. Alternatively, you can specify ALL_TRAFFIC which routes all traffic, including public internet traffic, through the connector and out via your VPC’s internet egress. The PRIVATE_RANGES_ONLY option routes only traffic destined for RFC 1918 private IP addresses through the connector, while public internet traffic bypasses it.
The connector field points to the specific VPC Network Access connector resource. You create these connectors in the Google Cloud console or via gcloud commands. They are regional resources and must reside in the same region as your Cloud Run service. When creating a connector, you specify which VPC network it should connect to and the subnetwork it will use. This subnetwork needs to have enough available IP addresses for the connector instances.
Consider the network field in the VPC Access connector configuration. If you don’t explicitly specify a subnetwork for the connector, it will use the default subnetwork of the VPC you’ve associated it with. This is convenient for quick setups but can lead to IP address exhaustion if the default subnetwork is already heavily utilized by other resources. It’s best practice to create a dedicated subnetwork for your VPC Access connectors.
The most surprising aspect is that your Cloud Run service doesn’t actually reside within your VPC network in the traditional sense. It remains a fully managed serverless offering. The VPC Network Access connector acts as a proxy, making it appear as if the traffic originates from within your VPC, enabling seamless private communication without complex network configurations or the need to manage your own ingress/egress gateways for this specific purpose.
The next step in securing your private workloads is often implementing Identity-Aware Proxy (IAP) for services that still require controlled public access, or exploring Private Service Connect for more advanced private connectivity patterns.