Skip to content

Instantly share code, notes, and snippets.

@aamir814
Last active January 16, 2025 18:22
Show Gist options
  • Select an option

  • Save aamir814/6156fc3b378bf39470875d01093feb63 to your computer and use it in GitHub Desktop.

Select an option

Save aamir814/6156fc3b378bf39470875d01093feb63 to your computer and use it in GitHub Desktop.
Connect to a Cloud SQL instance using Private Service Connect
#!/usr/bin/env bash
#####################################################################
# Purpose: Following is an example on how to connect to Cloud SQL instance
# from different VPC using Private Service Connect. I followed
# the instructions mentioned in Google document
# (1st URL in refrence section). Created two VPCs
#
# REFERENCES
# - https://cloud.google.com/sql/docs/postgres/configure-private-service-connect
# - https://cloud.google.com/blog/products/databases/private-service-connect-for-cloud-sql-databases/?utm_source=convertkit&utm_medium=email&utm_campaign=GCP%20Newsletter%20#394%20-%2013627950
#####################################################################
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_USER=$(gcloud config get-value core/account) # set current user
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
export IDNS=${PROJECT_ID}.svc.id.goog # workflow identity domain
# CHANGEME (OPT)
export GCP_REGION="us-central1"
export GCP_ZONE="us-central1-a"
export NETWORK_NAME="default"
export SQL_NETWORK_NAME="cloudsql"
export SUBNET_NAME="sql-psc"
# enable apis
gcloud services enable compute.googleapis.com \
storage.googleapis.com \
sqladmin.googleapis.com \
dns.googleapis.com
# configure gcloud sdk
gcloud config set compute/region $GCP_REGION
gcloud config set compute/zone $GCP_ZONE
########## create VPC for Cloud SQL ##########
gcloud compute networks create $SQL_NETWORK_NAME \
--subnet-mode=auto
# default firewall rules
gcloud compute firewall-rules create ${SQL_NETWORK_NAME}-allow-internal \
--action=ALLOW \
--direction=INGRESS \
--network=${SQL_NETWORK_NAME} \
--priority=1000 \
--rules=tcp:0-65535,udp:0-65535,icmp \
--source-ranges=10.128.0.0/9
gcloud compute firewall-rules create ${SQL_NETWORK_NAME}-allow-ssh \
--action=ALLOW \
--direction=INGRESS \
--network=${SQL_NETWORK_NAME} \
--priority=1000 \
--rules=tcp:22 \
--source-ranges=0.0.0.0/0
gcloud compute firewall-rules create ${SQL_NETWORK_NAME}-allow-icmp \
--action=ALLOW \
--direction=INGRESS \
--network=${SQL_NETWORK_NAME} \
--priority=1000 \
--rules=icmp \
--source-ranges=0.0.0.0/0
gcloud compute firewall-rules create ${SQL_NETWORK_NAME}-allow-db \
--action=ALLOW \
--direction=INGRESS \
--network=${SQL_NETWORK_NAME} \
--priority=1000 \
--rules=tcp:5432 \
--source-ranges=10.10.0.0/24
# add a subnet
gcloud compute networks subnets create $SUBNET_NAME \
--network=$SQL_NETWORK_NAME \
--range=10.10.0.0/24 \
--region=$GCP_REGION
########## create a cloud sql instance ##########
export DB_INSTANCE_NAME="pgtest"
export DB_INSTANCE_VERSION="POSTGRES_15"
gcloud sql instances create $DB_INSTANCE_NAME \
--project=$PROJECT_ID \
--region=$GCP_REGION \
--enable-private-service-connect \
--allowed-psc-projects=$PROJECT_ID \
--availability-type=regional \
--no-assign-ip \
--cpu=2 \
--memory=7680MB \
--database-version=$DB_INSTANCE_VERSION
# To update an existing Cloud SQL Instance run the following
# gcloud sql instances patch $DB_INSTANCE_NAME \
# --project=$PROJECT_ID \
# --allowed-psc-projects=$PROJECT_ID
# create postgres database
export DB_NAME="psc"
gcloud sql databases create $DB_NAME \
--instance=$DB_INSTANCE_NAME
# override postgres password
gcloud sql users set-password postgres \
--instance=$DB_INSTANCE_NAME \
--prompt-for-password
# verify db
gcloud sql databases list --instance $DB_INSTANCE_NAME
# Get the service attachment URI
SVC_ATTACH=$(gcloud sql instances describe $DB_INSTANCE_NAME --format='value(pscServiceAttachmentLink)')
########## create PSC endpoint for each VPC ##########
gcloud compute addresses create psc-sql-ep \
--project=$PROJECT_ID \
--region=$GCP_REGION \
--subnet=$SUBNET_NAME \
--purpose=GCE_ENDPOINT
# verify the address and make a note of it. These will be used in creating DNS record
gcloud compute addresses list --filter="name=( 'NAME' 'psc-sql-ep')" --project=$PROJECT_ID
########## create forwarding-rule ##########
gcloud compute forwarding-rules create forward-sql-rule-1 \
--project=$PROJECT_ID \
--region=$GCP_REGION \
--network=$SQL_NETWORK_NAME \
--target-service-attachment=$SVC_ATTACH \
--address=psc-sql-ep
# verify the forwarding-rules
gcloud compute forwarding-rules describe forward-sql-rule-1 \
--project=$PROJECT_ID \
--region=$GCP_REGION
# List PSC endpoints to validate
gcloud compute forwarding-rules list --filter="name=( 'NAME' 'forward-sql-rule-1')" \
--regions=$GCP_REGION
########## Configure DNS managed zone ##########
# get Cloud SQL DNS name
SQL_DNS_NAME=$(gcloud sql instances describe $DB_INSTANCE_NAME --project=$PROJECT_ID --format='value(dnsName)')
# create DNS zone in each VPC
gcloud dns managed-zones create sql-zone \
--project=$PROJECT_ID \
--description="zone to connect to cloud sql in different vpc" \
--dns-name=$SQL_DNS_NAME \
--networks=$SQL_NETWORK_NAME \
--visibility=private
# create DNS record for zone. Note the IP address is from endpoint
# from above step
gcloud dns record-sets create $SQL_DNS_NAME \
--project=$PROJECT_ID \
--type=A \
--rrdatas=10.10.0.4 \
--zone=sql-zone
gcloud compute addresses describe psc-sql-ep
########## create VM in VPC to test Cloud SQL connection ##########
# VM in cloudsql VPC
gcloud compute instances create sql-vpc \
--project=$PROJECT_ID \
--zone=$GCP_ZONE \
--machine-type=e2-micro \
--network-interface=network-tier=PREMIUM,stack-type=IPV4_ONLY,subnet=$SQL_NETWORK_NAME \
--service-account=974657876698-compute@developer.gserviceaccount.com \
--create-disk=auto-delete=yes,boot=yes,device-name=sql-vpc,image=projects/debian-cloud/global/images/debian-11-bullseye-v20231010,mode=rw,size=10,type=projects/csql-project/zones/us-central1-a/diskTypes/pd-balanced \
--no-shielded-secure-boot \
--shielded-vtpm \
--shielded-integrity-monitoring \
--labels=goog-ec-src=vm_add-gcloud \
--reservation-affinity=any
# ssh to each server
gcloud compute ssh sql-vpc --zone=$GCP_ZONE
# install psql client on both machines
# sudo apt-get update
# sudo apt-get install -y postgresql-client-13
# validate that you are in cloudsql VPC
# curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/?recursive=true&alt=text" -H "Metadata-Flavor: Google";echo
# connect to database using DNS name
# psql -h 2f78f3566258.3uwpf52ydytcp.us-central1.sql.goog. -U postgres -d psc
########## clean up ##########
gcloud compute instances delete sql-vpc
gcloud dns record-sets delete $SQL_DNS_NAME --type=A --zone=sql-zone
gcloud dns managed-zones delete sql-zone
gcloud compute forwarding-rules delete forward-sql-rule-1
gcloud compute addresses delete psc-sql-ep
gcloud sql instances delete $DB_INSTANCE_NAME
gcloud compute networks subnets delete $SUBNET_NAME
gcloud compute firewall-rules delete ${SQL_NETWORK_NAME}-allow-ssh
gcloud compute firewall-rules delete ${SQL_NETWORK_NAME}-allow-db
gcloud compute firewall-rules delete ${SQL_NETWORK_NAME}-allow-icmp
gcloud compute firewall-rules delete ${SQL_NETWORK_NAME}-allow-internal
gcloud compute networks delete $SQL_NETWORK_NAME
@aamir814
Copy link
Author

Connect to a Cloud SQL instance using Private Service Connect


Some customers have asked on how to connect to Cloud SQL using private IP address from different VPCs. This example shows how to connect to Cloud SQL instance using private IP from different VPC.

Result


image

@mikesparr
Copy link

Nice!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment