Provisioning Cloud SQL with Private Service Connect Using Terraform

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:

  • Cloud SQL API
  • Cloud Run API
  • Cloud Build API
  • Artifact Registry API
  • Cloud Logging API
  • Serverless VPC Access API
  • Network Connectivity API
  • Compute Engine API

Terraform Project Overview

The Terraform project sets up the following resources on Google Cloud Platform (GCP):

Virtual Private Cloud (VPC) Network and Subnets:?

  • A VPC network named nw1-vpc is created, along with two subnets (nw1-vpc-sub1-us-central1 and nw1-vpc-sub3-us-west1) in different regions.

Cloud SQL Instances:

  • Private Service Connect (PSC) Instance: A Cloud SQL instance named psc-instance is created with Private Service Connect enabled, allowing secure access from Google Cloud services and resources.

Networking Components:

  • Firewall rules are defined to control access to the VPC network.
  • A NAT gateway is configured to allow instances in the VPC network to access the internet.

Service Account and IAM Roles:?

  • A service account named cloudsql-service-account-id is created and granted the necessary roles for accessing Cloud SQL instances.

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:

VPC Connector:?

  • You can enable your Cloud Run service or job to send traffic to a VPC network by configuring a Serverless VPC Access connector. A VPC Connector named private-cloud-sql is provisioned for enabling Private Service Connect access from Google Cloud services like Cloud Run in network.tf.

Direct VPC egress:?

  • You can enable your Cloud Run service or job to send traffic to a VPC network by using Direct VPC egress with no Serverless VPC Access connector required.

Terraform Project

  • Provider Configuration

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.

  • Virtual Private Cloud (VPC) Network and Subnets

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
}        

  • Private Service Connect (PSC) Instance

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"
  }
}        

  • Networking Components

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]
}        

  • Service Account and IAM Roles

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}"
}        

  • VPC Connector

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:

  • SERVICE_ATTACHMENT_URI (pscServiceAttachmentLink)

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:

  • DNS Entry(dnsName)

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:

  • ZONE_NAME: the name of the DNS zone
  • PROJECT_ID: the ID or project number of the Google Cloud project that contains the zone
  • DESCRIPTION: a description of the zone (for example, a DNS zone for the Cloud SQL instance)
  • DNS_NAME: the DNS name for the zone, such as REGION_NAME.sql.goog. (where REGION_NAME is the region name for the zone)
  • NETWORK_NAME: the name of the VPC network


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:

  • DNS_NAME: the DNS name that you retrieved earlier in this procedure.
  • RRSET_TYPE: the resource record type of the DNS record set (for example, A).
  • RR_DATA: the IP address allocated for the Private Service Connect endpoint (for example, 198.51.100.5). You can also enter multiple values such as rrdata1 rrdata2 rrdata3 (for example, 10.1.2.3 10.2.3.4 10.3.4.5).


Source Code

Here on?GitHub.


References

https://cloud.google.com/vpc/docs/private-service-connect

https://cloud.google.com/run/docs/configuring/connecting-vpc

https://cloud.google.com/run/docs/configuring/vpc-direct-vpc

https://cloud.google.com/run/docs/configuring/vpc-connectors#console


要查看或添加评论,请登录

Henry Xiloj Herrera的更多文章

社区洞察

其他会员也浏览了