Cloud SQL Terraform: Infrastructure as Code Guide for Private PostgreSQL Deployment

Cloud SQL Terraform enables fully automated, private PostgreSQL deployments using Private Service Connect, IAM authentication, and declarative HCL configuration.

Google Cloud SQL provides a fully-managed relational database service that you can provision entirely through Terraform infrastructure as code. By describing your desired database state in HashiCorp Configuration Language (HCL), you obtain reproducible, version-controlled infrastructure deployable across environments without manual console work.


Core Architecture Components

The Google Skills repository demonstrates a production-grade Cloud SQL Terraform module built around five key components.

Cloud SQL Instance Resource

The google_sql_database_instance resource defines the database engine and connectivity model. According to assets/main.tf in the N-Tier Serverless Web App skill, production deployments should enable Private Service Connect (psc_enabled = true) and explicitly disable public IP access (ipv4_enabled = false).

Key settings include:

  • database_version – e.g., "POSTGRES_18" for PostgreSQL 18 Enterprise
  • availability_type – "REGIONAL" for high availability across zones
  • tier – machine type such as "db-custom-2-7680"

PSC Forwarding Rule

Private Service Connect requires a google_compute_forwarding_rule that maps a reserved internal IP to the Cloud SQL service attachment. This keeps all database traffic inside your VPC without traversing the public internet.

IAM-Authenticated Database Users

The google_sql_user resource with type = "CLOUD_IAM_USER" eliminates password management. Users authenticate through Google's IAM system and connect via the Cloud SQL Auth Proxy.

Service Account Permissions

Applications receive database access through google_project_iam_member bindings granting roles/cloudsql.client. This follows least-privilege principles documented in references/iam-security.md.

Optional Monitoring Configuration

The insights_config block within google_sql_database_instance enables Query Insights for performance analysis without additional agents.


Complete Terraform Configuration Example

This production-ready snippet from assets/main.tf provisions a private PostgreSQL instance with IAM authentication and Query Insights:

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

# -------------------------------------------------------------------------

# Cloud SQL instance (Private Service Connect, no public IP)

# -------------------------------------------------------------------------

resource "google_sql_database_instance" "postgres" {
  name                = var.instance_name
  database_version    = "POSTGRES_18"
  region              = var.region
  tier                = var.instance_tier
  deletion_protection = true

  settings {
    tier              = var.instance_tier
    activation_policy = "ALWAYS"
    availability_type = "REGIONAL"

    ip_configuration {
      ipv4_enabled = false
      psc_config {
        psc_enabled = true
      }
    }

    insights_config {
      query_insights_enabled = true
    }
  }
}

# -------------------------------------------------------------------------

# PSC forwarding rule (private IP in consumer VPC)

# -------------------------------------------------------------------------

resource "google_compute_forwarding_rule" "psc_sql" {
  name                  = "${var.instance_name}-psc"
  region                = var.region
  load_balancing_scheme = "INTERNAL"
  network               = var.vpc_network
  ip_address            = var.psc_ip
  target                = google_sql_database_instance.postgres.service_attachment_self_link
  ports                 = ["5432"]
}

# -------------------------------------------------------------------------

# IAM binding for application service account

# -------------------------------------------------------------------------

resource "google_project_iam_member" "sql_client" {
  project = var.project_id
  role    = "roles/cloudsql.client"
  member  = "serviceAccount:${var.backend_service_account}"
}

# -------------------------------------------------------------------------

# Database and IAM-authenticated user

# -------------------------------------------------------------------------

resource "google_sql_database" "app_db" {
  name     = var.database_name
  instance = google_sql_database_instance.postgres.name
}

resource "google_sql_user" "app_user" {
  name     = var.db_user
  instance = google_sql_database_instance.postgres.name
  type     = "CLOUD_IAM_USER"
}

Deployment Workflow

Execute these steps to deploy your Cloud SQL Terraform configuration:

  1. Initialize Terraform – Download providers and modules:
terraform init
  1. Validate configuration – Catch syntax errors before any infrastructure changes:
terraform validate
  1. Plan changes – Review the execution plan with a dry-run:
terraform plan -out=tfplan
  1. Apply configuration – Provision resources after plan review:
terraform apply tfplan

Application Connectivity: Cloud SQL Auth Proxy

Cloud SQL Terraform pairs with the Cloud SQL Auth Proxy for secure, passwordless connections. In your Cloud Run service configuration, mount the proxy's Unix socket:

containers:
- name: app
  image: gcr.io/${PROJECT_ID}/my-app:latest
  volumeMounts:
  - name: cloudsql-instance
    mountPath: /cloudsql
volumes:
- name: cloudsql-instance
  cloudSqlInstance:
    instances: ["${PROJECT_ID}:${REGION}:${INSTANCE_NAME}"]

Your application connects through the socket path /cloudsql/${PROJECT_ID}:${REGION}:${INSTANCE_NAME} using IAM authentication—no passwords stored or transmitted.


Security Best Practices from the Source Code

The google/skills repository enforces several hardening patterns for Cloud SQL Terraform deployments:

Practice Implementation
No public IP exposure ipv4_enabled = false in ip_configuration block
Private connectivity only psc_enabled = true with PSC forwarding rule
Least-privilege networking Firewall rules allowing only TCP 5432 to PSC endpoint and TCP 443 for Auth Proxy token exchange
IAM-based authentication type = "CLOUD_IAM_USER" instead of built-in database passwords
Deletion protection deletion_protection = true to prevent accidental instance destruction

These patterns appear in SKILL.md and assets/main.tf within the N-Tier Serverless Web App skill directory.


Key Reference Files

File Location Purpose
SKILL.md skills/cloud/google-cloud-solution-n-tier-serverless-web-app/SKILL.md Architecture overview and Cloud SQL IaC patterns
assets/main.tf skills/cloud/google-cloud-solution-n-tier-serverless-web-app/assets/main.tf Complete Terraform module implementation
references/terraform-usage.md skills/cloud/spanner-basics/references/terraform-usage.md General Terraform style guide for extending modules
references/iam-security.md skills/cloud/workload-manager-basics/references/iam-security.md IAM authentication best practices
references/general-best-practices.md skills/cloud/workload-manager-basics/references/general-best-practices.md Cloud-native security principles

Summary

  • Cloud SQL Terraform enables fully declarative database provisioning through HCL configuration files tracked in version control
  • Private Service Connect with disabled public IP provides secure, VPC-native connectivity without internet exposure
  • IAM database authentication eliminates password management and integrates with Google Cloud's identity system
  • Query Insights offers built-in performance monitoring through the insights_config block
  • The google/skills repository provides production-tested modules at assets/main.tf with security hardening patterns documented in SKILL.md

Frequently Asked Questions

What is the difference between Private Service Connect and private IP for Cloud SQL?

Private Service Connect establishes a private, consumer-side endpoint that routes traffic through Google's network backbone without exposing IPs publicly. Traditional private IP requires VPC peering and allocates IP addresses from your VPC range. PSC offers simpler routing, better security boundaries, and is the recommended approach in the google/skills Cloud SQL Terraform modules.

How does IAM database authentication work with Terraform-managed Cloud SQL?

Set type = "CLOUD_IAM_USER" in the google_sql_user resource. Users authenticate with OAuth 2.0 tokens instead of passwords, and the Cloud SQL Auth Proxy validates these tokens automatically. Your Terraform configuration grants roles/cloudsql.client to service accounts, enabling applications to connect without credential files.

Can I enable high availability through Cloud SQL Terraform?

Yes. Set availability_type = "REGIONAL" in the settings block of google_sql_database_instance. This creates a synchronous standby in a different zone within the same region, providing automatic failover without data loss. The configuration in assets/main.tf demonstrates this pattern combined with deletion protection for production safety.

Should I use terraform.tfvars or environment variables for sensitive values?

Use environment variables prefixed with TF_VAR_ for sensitive values like project IDs and service account emails, or integrate with Google Secret Manager via the google_secret_manager_secret_version data source. Never commit credentials to terraform.tfvars in version control. The references/terraform-usage.md file shows variable passing patterns compatible with Cloud Shell and CI/CD pipelines.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →