Provisioning Cloud SQL with Private Service Connect Using Terraform
In this post, we'll explore how to provision Cloud SQL instances with Private Service Connect (PSC) connectivity using Terraform and then access them from a Spring Boot application deployed on Google Cloud Run. We'll leverage Terraform to create the necessary infrastructure and configure the networking components.
Enabled APIs
The following APIs need to be enabled for this project:
Terraform Project Overview
The Terraform project sets up the following resources on Google Cloud Platform (GCP):
Virtual Private Cloud (VPC) Network and Subnets:?
Cloud SQL Instances:
Networking Components:
Service Account and IAM Roles:?
Compare Direct VPC egress and VPC connectors
Cloud Run offers two methods for sending egress (outbound) traffic from a Cloud Run service or job to a VPC network:
Terraform Project
In the provider.tf file, we define the required providers and configure the Google Cloud provider with the project ID, region, and zone:
provider "google" {
project = var.project_id
region = var.region
zone = var.zone
}
The project_id, region, and zone variables are defined in the variables.tf file and assigned values in the terraform.tfvars file.
In the network.tf file, we create the VPC network and subnets:
resource "google_compute_network" "nw1-vpc" {
project = var.project_id
name = "nw1-vpc"
auto_create_subnetworks = false
mtu = 1460
}
resource "google_compute_subnetwork" "nw1-subnet1" {
name = "nw1-vpc-sub1-${var.region}"
network = google_compute_network.nw1-vpc.id
ip_cidr_range = "10.10.1.0/24"
region = var.region
private_ip_google_access = true
}
resource "google_compute_subnetwork" "nw1-subnet2" {
name = "nw1-vpc-sub3-us-west1"
network = google_compute_network.nw1-vpc.id
ip_cidr_range = "10.10.2.0/24"
region = var.sec_region
private_ip_google_access = true
}
In the main.tf file, we create the Cloud SQL instances with Private Service Conect option:
resource "google_sql_database_instance" "psc_instance" {
project = var.project_id
name = "psc-instance"
region = var.region
database_version = "POSTGRES_15"
deletion_protection = false
settings {
tier = "db-f1-micro"
ip_configuration {
psc_config {
psc_enabled = true
allowed_consumer_projects = ["<PROJECT_ID>"]
}
ipv4_enabled = false
}
availability_type = "REGIONAL"
}
}
resource "google_compute_global_address" "private_ip_address" {
name = google_compute_network.nw1-vpc.name
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.nw1-vpc.name
}
resource "google_service_networking_connection" "private_vpc_connection" {
network = google_compute_network.nw1-vpc.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}
In the serviceaccount.tf file, we create the service account and assign necessary roles:
resource "google_service_account" "cloudsql_service_account" {
project = var.project_id
account_id = "cloudsql-service-account-id"
display_name = "Service Account for Cloud SQL"
}
resource "google_project_iam_member" "member-role" {
depends_on = [google_service_account.cloudsql_service_account]
for_each = toset([
"roles/cloudsql.client",
"roles/cloudsql.editor",
"roles/cloudsql.admin",
"roles/secretmanager.secretAccessor",
"roles/secretmanager.secretVersionManager",
"roles/vpcaccess.serviceAgent"
])
role = each.key
project = var.project_id
member = "serviceAccount:${google_service_account.cloudsql_service_account.email}"
}
In the network.tf file, we create the VPC Connector for Private Service Connect access:
领英推荐
#****************************Equivalent gcloud command
/* gcloud compute networks vpc-access connectors create private-cloud-sql \
--region us-central1 \
--network nw1-vpc \
--range "10.10.3.0/28" \
--machine-type e2-micro \
--project <PROJECT-ID>*/
resource "google_vpc_access_connector" "private-cloud-sql" {
project = var.project_id
name = "private-cloud-sql"
region = var.region
network = google_compute_network.nw1-vpc.id
machine_type = "e2-micro"
ip_cidr_range = "10.10.3.0/28"
}
Private Service Connect Configuration
You can reserve an internal IP address for the Private Service Connect endpoint and create an endpoint with that address. To create the endpoint, you need the service attachment URI and the projects that are allowed for the instance.
To reserve an internal IP address for the Private Service Connect endpoint, use the gcloud compute addresses create command:
/*gcloud compute addresses create internal-address \
--project=<PROJECT-ID> \
--region=us-central1 \
--subnet=nw1-vpc-sub1-us-central1 \
--addresses=10.10.1.10*/
resource "google_compute_address" "internal_address" {
project = var.project_id
name = "internal-address"
region = var.region
address_type = "INTERNAL"
address = "10.10.1.10" #"INTERNAL_IP_ADDRESS"
subnetwork = google_compute_subnetwork.nw1-subnet1.name
}
To create the Private Service Connect endpoint and point it to the Cloud SQL service attachment, use the gcloud compute forwarding-rules create command:
gcloud sql instances describe - displays configuration and metadata about a Cloud SQL instance
Get from this command:
gcloud sql instances describe psc-instance --project PROJECT_ID
gcloud compute forwarding-rules create psc-service-attachment-link \
--address=internal-address\
--project=PROJECT_ID \
--region=us-central1\
--network=nw1-vpc\
--target-service-attachment=SERVICE_ATTACHMENT_URI
Cloud SQL doesn't create DNS records automatically. Instead, the instance lookup API response provides a suggested DNS name. We recommend that you create the DNS record in a private DNS zone in the corresponding VPC network. This provides a consistent way of using the Cloud SQL Auth Proxy to connect from different networks.
Get from this command:
gcloud sql instances describe psc-instance --project PROJECT_ID
In the response, verify that the DNS name appears. This name has the following pattern: INSTANCE_UID.PROJECT_DNS_LABEL.REGION_NAME.sql.goog.. For example: 1a23b4cd5e67.1a2b345c6d27.us-central1.sql.goog.
To create a private DNS zone, use the gcloud dns managed-zones create command. This zone is associated with the VPC network that's used to connect to the Cloud SQL instance through the Private Service Connect endpoint.
gcloud dns managed-zones create cloud-sql-dns-zone\
--project=PROJECT_ID \
--description="DNS zone for the Cloud SQL instance"\
--dns-name=DNS_NAME \
--networks=nw1-vpc\
--visibility=private
Make the following replacements:
After you create the Private Service Connect endpoint, to create a DNS record in the zone, use the gcloud dns record-sets create command:
gcloud dns record-sets create DNS_NAME \
--project=PROJECT_ID \
--type=A\
--rrdatas=10.10.1.10\
--zone=cloud-sql-dns-zone
Make the following replacements:
Source Code
Here on?GitHub.
References