Terraform for Google Cloud SQL: Provisioning, Hardening, and Operations

Introduction

Terraform provides a declarative path to create, configure, and operate Google Cloud SQL instances without manual console steps. The workflow centers on the google_sql_database_instance resource, supporting MySQL and PostgreSQL editions, combined with databases, users, Secret Manager integration, and network connectivity patterns such as Private Service Connect. Reference implementations show both module-based usage via terraform-google-modules/terraform-google-sql-db and direct HCL for development or testing deployments.

Module Landscape and Version Constraints

The terraform-google-modules/terraform-google-sql-db repository makes it easy to create Google CloudSQL instance and implement high availability settings. This module consists of the following submodules. See more details in each module's README.

The module is meant for use with Terraform 1.3+ and tested using Terraform 1.6+. If you find incompatibilities using Terraform >=1.13, please open an issue.

The current version is 26.X. The following guides are available to assist with upgrades:

  • 1.X -> 2.0
  • 2.X -> 3.0
  • 3.X -> 4.0
  • 10.X -> 11.0
  • 11.X -> 12.0
  • 13.X -> 14.0
  • 14.X -> 15.0
  • 16.X -> 17.0
  • 19.X -> 20.0
  • 20.X -> 21.0
  • 21.X -> 22.0
  • 22.X -> 23.0
  • 23.X -> 24.0
  • 25.X -> 26.0

The root module has been deprecated.

Upgrade Path Reference

From Version To Version Guidance
1.X 2.0 Upgrade guide available
25.X 26.0 Upgrade guide available
26.X current Module is tested with Terraform 1.6+

Project Structure and Provider Configuration

Managing Cloud SQL with Terraform requires a clear layout and provider setup.

Prerequisites
- Google Cloud SDK installed and configured
- Terraform installed version 1.0.0 or later
- A GCP project with billing enabled
- Basic understanding of databases

A common project structure is:

. ├── main.tf # Main Terraform configuration file ├── variables.tf # Variable definitions ├── outputs.tf # Output definitions ├── terraform.tfvars # Variable values └── modules/ └── cloudsql/ ├── main.tf # Cloud SQL specific configurations ├── variables.tf # Module variables ├── databases.tf # Database configurations └── outputs.tf # Module outputs

Provider Configuration

hcl terraform { required_providers { google = { source = "hashicorp/google" version = "~> 4.0" } } } provider "google" { project = var.project_id region = var.region }

Variables

hcl variable "project_id" { description = "The ID of the GCP project" type = string } variable "region" { description = "The region to deploy resources to" type = string default = "us-central1" } variable "instance_name" { description = "Name of the Cloud SQL instance" type = string } variable "database_version" { description = "The MySQL or PostgreSQL version to use" type = string default = "POSTGRES_14" } variable "tier" { description = "The machine type to use" type = string default = "db-f1-micro" }

Core Resources for a Learning Deployment

Deploying GCP Cloud SQL with Terraform can be focused on development or testing purposes. The note is that currently only for MySQL and PostgreSQL is covered, not SQL Server.

Core resources used:

  • Cloud SQL DB Instance
  • Cloud SQL Database
  • Cloud SQL User
  • Secret Manager Secret
  • Secret Manager Secret Version
  • Ephemeral Random Password

This varies depending on the edition you're using, but ENTERPRISE_PLUS will have have more machine sizing requirements and tiers compared to ENTERPRISE. As this is a "learning" deployment, focus is more on the different database configurations.

To see available tiers in a region:

gcloud sql tiers list --filter=AVAILABLE_REGIONS=[YOUR_REGION_HERE]

Machine type guidance from reference material:

  • f1-micro works okay and is the current default machine_type
  • g1-small is highly recommended for a better overall experience
  • f1-micro takes quite a bit longer to provision due to how little memory it has

Minimal Instance Definition

The simplest setup to get a working database:

hcl resource "google_sql_database_instance" "default" { name = "example-sql" database_version = "POSTGRES_15" region = "us-central1" settings { tier = "db-f1-micro" } } resource "google_sql_user" "users" { name = "example-user" instance = google_sql_database_instance.default.name password = var.db_password } resource "google_sql_database" "database" { name = "example-db" instance = google_sql_database_instance.default.name }

Never hardcode DB passwords in .tf files.

Full Example with Secret Manager and Cloud Run

This Terraform shows a full example of creating a Cloud SQL instance with authentication stored in Secret Manager, and configuring a Cloud Run instance with those secrets.

hcl data "google_project" "project" { } resource "google_project_service" "secretmanager_api" { service = "secretmanager.googleapis.com" disable_on_destroy = false } resource "google_project_service" "sqladmin_api" { service = "sqladmin.googleapis.com" disable_on_destroy = false } resource "google_project_service" "cloudrun_api" { service = "run.googleapis.com" disable_on_destroy = false } resource "google_sql_database_instance" "default" { name = "mysql-instance-1" region = "us-central1" database_version = "MYSQL_8_0" root_password = "abcABC123!" settings { tier = "db-f1-micro" password_validation_policy { min_length = 6 complexity = "COMPLEXITY_DEFAULT" reuse_interval = 2 disallow_username_substring = true enable_password_policy = true } } deletion_protection = false depends_on = [google_project_service.sqladmin_api] } resource "google_secret_manager_secret" "dbuser" { secret_id = "dbusersecret" replication { auto {} } depends_on =

Creating a Cloud SQL instance with this pattern takes ~15 minutes to fully spin up.

Network, Security and Operational Best Practices

SSL/TLS
- Regular password rotation
- Use IAM authentication
-

High Availability:
- Enable automated backups
- Configure failover replicas
- Use appropriate regions

Performance:
- Choose appropriate machine type
- Monitor query performance
- Configure maintenance windows

Cost Optimization:
- Right-size instances
- Use committed use discounts
- Monitor usage patterns

Best Practices and Tips

Backup Strategy:
- Enable point-in-time recovery
- Test backup restoration
- Configure backup retention

Monitoring:
- Set up alerts
- Monitor performance metrics
- Track connection counts

Security:
- Regular security audits
- Implement network security
- Manage access controls

Common Operations

Creating Resources

  • terraform init
  • terraform plan
  • terraform apply

Connecting to Database

cloud_sql_proxy -instances=<CONNECTION_NAME>=tcp:5432

Destroying Resources

  • Remove deletion protection first
    terraform apply -var="deletion_protection=false"
  • terraform destroy

Private Service Connect Workflow

Creating the CloudSQL instance with PSC attachment may take up to 5+ minutes.

Verification steps after apply:

  • After completion, Go to SQL in the console, select the newly created psc-sql-db database instance.
  • On the left side expand the SQL options slideout and select Connections
  • Under the summary tab you can see information about the connection.
  • Copy the Service attachment address and save it somewhere on your system.
  • You will need this to complete task 3 step 8.
  • On the left side expand the SQL options slideout and select Users.
  • You should see a user called testsql with password cloudsql24

Task 3 involves setting up environment for consumer project with Terraform:

In the consumer project, we will create a custom VPC with Firewall rules and subnet

Operational Properties Table

Property Typical Value Note
Provider hashicorp/google version ~> 4.0
Default Region us-central1 configurable via var.region
Default DB Version POSTGRES_14 example POSTGRES_15 also shown
Default Tier db-f1-micro g1-small recommended
Instance Provision Time ~15 minutes PSC attachment ~5+ minutes
Deletion Protection false in example set true to prevent accidental delete

Conclusion

Terraform enables version controlled, repeatable Cloud SQL provisioning with safety through plan previews and drift detection. The module path via terraform-google-modules/terraform-google-sql-db offers structured submodules and a defined upgrade cadence up to version 26.X with Terraform 1.3+ support and testing on Terraform 1.6+. Direct HCL remains valuable for learning deployments targeting MySQL and PostgreSQL, where core resources include Cloud SQL DB Instance, Database, User, and Secret Manager integration.

Machine sizing decisions impact provisioning time and experience, with f1-micro acceptable for minimal tests but g1-small recommended for better overall experience. Security posture improves with Secret Manager for credentials, password validation policies, IAM authentication, regular password rotation, and network controls such as Private Service Connect. High availability requires automated backups, failover replicas, and appropriate region selection.

Operational workflows follow init, plan, apply for creation, and require deletion protection to be cleared before destroy. Connecting via Cloud SQL Proxy uses the instance connection name. Monitoring, backup retention, point-in-time recovery testing, and maintenance windows complete a production-ready baseline. The combination of module usage for standardized HA setups and explicit resource definitions for developer sandbox instances covers the breadth of Cloud SQL management with Terraform.

Sources

  1. terraform-google-modules/terraform-google-sql-db
  2. thecloudpanda.com/blog/gcp-cloudsql-terraform/
  3. Neutrollized/gcp-cloud-sql
  4. docs.cloud.google.com/run/docs/samples/cloudrun-connect-cloud-sql-parent-tag
  5. dev.to/terraformmonkey/gcp-cloud-sql-terraform-quick-start-guide-2mk4
  6. codelabs.developers.google.com/codelabs/cloudsql-psc-terraform

Related Posts