Skip to content

Cloud SQL for Postgres

Runway supports connecting to unmanaged Cloud SQL for Postgres instances from your GKE workloads. This allows you to connect workloads to an existing database in a different project.

Before configuring your GKE workload, complete the shared setup steps in the Cloud Run CloudSQL documentation:

  1. Enable PSC on your Cloud SQL instance
  2. Obtain PSC details (DNS name, service attachment link, connection name)
  3. Update the provisioner - use config/runtimes/gke/cloud-sql/unmanaged.yml instead of the cloud-run path

In the project where your Cloud SQL instance lives, grant the Cloud SQL Client role to your GKE workload’s service account.

Your workload’s service account will have the following format:

gke-<Workload ID>@<Runway Project ID>.iam.gserviceaccount.com

For example:

Using the gcloud CLI:

Terminal window
gcloud projects add-iam-policy-binding <DB Project ID> \
--member=serviceAccount:gke-<Runway workload ID>@<Runway Project ID>.iam.gserviceaccount.com \
--role=roles/cloudsql.client \
--condition="expression=resource.name == 'projects/<DB Project ID>/instances/<DB Instance ID>',title=access_specific_db"

Terraform example:

resource "google_project_iam_member" "runway-workload-cloudsql-client" {
project = var.project
role = "roles/cloudsql.client"
member = "serviceAccount:gke-<Runway workload ID>@<Runway Project ID>.iam.gserviceaccount.com"
condition {
title = "Cloud SQL client access for Runway workload"
expression = "resource.name == \"projects/${var.project}/instances/<DB instance ID>\""
}
}

Add cloudsql_instances to your gke-service.yaml:

gke-service.yaml
apiVersion: runway/v1
kind: RunwayKubernetesDeployment
your-service-gke:
serviceMixins:
- "runway-gke.service-mixin"
cloudsql_instances:
- instance_connection_name: <project>:<region>:<instance>

For multiple instances:

cloudsql_instances:
- instance_connection_name: project-a:us-east1:db-users
- instance_connection_name: project-b:us-east1:db-orders

The Cloud SQL Auth Proxy exposes databases on localhost with sequential ports starting at 5432:

InstancePort
First5432
Second5433
Third5434

Connect using:

  • Host: 127.0.0.1
  • Port: 5432 (first instance), 5433 (second), etc.
  • Username and password via environment variables (see secrets management)
  1. Verify instance_connection_name is correct
  2. Check proxy sidecar logs from grafana (see logging):
    SELECT
    TimestampTime as "timestamp",
    Body as "body",
    SeverityText as "level",
    Attributes as "labels"
    FROM
    "observability"."otel_logs"
    WHERE
    (
    timestamp >= $__fromTime
    AND timestamp <= $__toTime
    )
    AND (
    labels['service.name'] = '{runway-service-id}-{staging|production}'
    )
    AND (labels['k8s.container.name'] = 'cloud-sql-proxy')
    ORDER BY
    timestamp DESC
    LIMIT
    1000
  3. Ensure PSC endpoint is configured in provisioner