Cloud SQL is a managed relational database service on Google Cloud. Terraform provides declarative configuration for Cloud SQL instances, making it possible to codify instance settings, backups, high availability, network access, and secret management. The Terraform Google provider for Cloud SQL is the primary interface, and community modules such as terraform-google-sql simplify reuse.
Terraform and Cloud SQL Module Landscape
The terraform-google-sql module 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.
This 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.
The module structure supports modular adoption for production workloads where high availability and upgrade paths matter. Version pinning and upgrade guides reduce risk when moving between major releases.
Prerequisites and Project Structure
Managing Cloud SQL with Terraform requires Google Cloud SDK installed and configured, Terraform installed version 1.0.0 or later, a GCP project with billing enabled, and basic understanding of databases.
A common project structure separates concerns:
.
├── 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
This layout isolates Cloud SQL specific configurations from provider and variable definitions.
Provider Configuration and Variables
Provider Configuration
terraform {
requiredproviders {
google = {
source = "hashicorp/google"
version = "~> 4.0"
}
}
}
provider "google" {
project = var.projectid
region = var.region
}
Variables
variable "projectid" {
description = "The ID of the GCP project"
type = string
}
variable "region" {
description = "The region to deploy resources to"
type = string
default = "us-central1"
}
variable "instancename" {
description = "Name of the Cloud SQL instance"
type = string
}
variable "databaseversion" {
description = "The MySQL or PostgreSQL version to use"
type = string
default = "POSTGRES14"
}
variable "tier" {
description = "The machine type to use"
type = string
default = "db-f1-micro"
}
Provider version constraints and variable defaults provide a safe baseline for development and testing.
Basic Cloud SQL Instance Configuration
Databases are the one piece of infrastructure where getting the configuration wrong hurts the most. A misconfigured Cloud SQL instance can lead to data loss, downtime, or security breaches. Managing your database infrastructure with Terraform ensures that your configurations are reviewed, version-controlled, and reproducible.
This guide covers creating Cloud SQL instances with Terraform, with a focus on the settings that matter most for production: backups, high availability, security, and maintenance.
Basic Cloud SQL Instance
Let us start with a PostgreSQL instance and build up from there:
sql.tf - Basic Cloud SQL PostgreSQL instance
resource "googlesqldatabaseinstance" "main" {
name = "main-db"
databaseversion = "POSTGRES15"
region = var.region
project = var.projectid
settings {
tier = "db-custom-2-8192" # 2 vCPUs, 8GB RAM
disktype = "PDSSD"
disksize = 50
diskautoresize = true
diskautoresizelimit = 500 # Max 500GB
Prevent deletion through the Cloud SQL API, gcloud, Console, and Terraform
deletionprotectionenabled = true
ipconfiguration {
ipv4enabled = false # Disable public IP
privatenetwork = googlecompute_network.main.id
}
}
Prevent accidental Terraform deletion
deletion_protection = true
}
A few important choices here:
- Custom machine type: The
db-custom-VCPU-RAM
format lets you pick exactly the CPU and memory you need. - SSD disk: Always use PD_SSD for database workloads
Deletion protection is applied both at the GCP level via deletionprotectionenabled and at Terraform level via deletion_protection.
Network and Security Settings
Network Configuration is a core concern for Cloud SQL.
resource
IP configuration options include disabling public IPv4 and attaching a private network. Use private IP only. Never expose Cloud SQL to the public internet.
Security best practices include:
- 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
Additional production guidance:
- Use private IP only. Never expose Cloud SQL to the public internet.
- Enable PITR. Point-in-time recovery is your safety net for data corruption and accidental deletions.
- Use REGIONAL availability for production databases. The cost of HA is worth the uptime.
- Store passwords in Secret Manager, and use write-only Terraform arguments or tightly protected remote state for secret values.
- Enable disk autoresize to prevent out-of-space failures.
- Set maintenance windows during low-traffic periods.
- Log slow queries using database flags to identify performance issues early.
High Availability, Backups and Maintenance
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
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
The combination of automated backups, point-in-time recovery, and high availability provides the resilience that production databases need.
Machine Types and Tiers
Deploying GCP Cloud SQL with Terraform. Learn about the different configuration, security, and connectivity options. I don't focus on a lot of the enterprise-level settings, and is mostly aimed at educating developers who wants/needs to spin up a SQL database instance for development or testing purposes. If you want to compare this with the different Cloud SQL "presets" in the GCP console, this would be closer to a "Sandbox".
NOTE: currently only for MySQL and PostgreSQL.
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, I'm focused more on the different database configurations, but if you want to see the full list of available in your region, run:
gcloud sql tiers list --filter=AVAILABLEREGIONS=[YOURREGION_HERE]
RECOMMENDED: Although f1-micro
works okay (it's the current default machine_type
), I highly recommend starting out with the g1-small
for a better overall experience. The f1-micro
takes quite a bit longer to provision due to how little memory it has
Machine type selection affects provisioning time and performance. The table below summarizes common guidance from reference material.
| Tier | Typical Use | Notes |
|---|---|---|
| db-f1-micro | Development / testing | Current default machine_type |
| g1-small | Recommended learning | Better overall experience than f1-micro |
| db-custom-2-8192 | Production baseline | 2 vCPUs, 8GB RAM example |
| db-custom-VCPU-RAM | Custom production | Format lets you pick CPU and memory |
Secret Manager Integration and Cloud Run Connectivity
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.
Terraform
data "google_project" "project" {
}
Enable Secret Manager API
resource "googleprojectservice" "secretmanagerapi" {
service = "secretmanager.googleapis.com"
disableon_destroy = false
}
Enable SQL Admin API
resource "googleprojectservice" "sqladminapi" {
service = "sqladmin.googleapis.com"
disableon_destroy = false
}
Enable Cloud Run API
resource "googleprojectservice" "cloudrunapi" {
service = "run.googleapis.com"
disableon_destroy = false
}
Creates SQL instance (~15 minutes to fully spin up)
resource "googlesqldatabaseinstance" "default" {
name = "mysql-instance-1"
region = "us-central1"
databaseversion = "MYSQL80"
rootpassword = "abcABC123!"
settings {
tier = "db-f1-micro"
passwordvalidationpolicy {
minlength = 6
complexity = "COMPLEXITYDEFAULT"
reuseinterval = 2
disallowusernamesubstring = true
enablepasswordpolicy = true
}
}
set deletion_protection to true, will ensure that one cannot accidentally delete this instance by
use of Terraform whereas deletion_protection_enabled flag protects this instance at the GCP level.
deletionprotection = false
dependson = [googleprojectservice.sqladmin_api]
}
Create dbuser secret
resource "googlesecretmanagersecret" "dbuser" {
secretid = "dbusersecret"
replication {
auto {}
}
depends_on =
Storing credentials in Secret Manager decouples secrets from Terraform state and enables secure access from Cloud Run and other workloads.
Common Operations
Creating Resources
terraform init
terraform plan
terraform apply
Connecting to Database
Using Cloud SQL Proxy
cloudsqlproxy -instances=
Destroying Resources
Remove deletion protection first
terraform apply -var="deletion_protection=false"
terraform destroy
Deletion protection must be disabled before destroy operations to prevent accidental removal.
Conclusion
Cloud SQL with Terraform gives you a fully codified database setup that you can review, version, and replicate across environments. The combination of automated backups, point-in-time recovery, and high availability provides the resilience that production databases need. Start with these configurations as a baseline and tune the machine type, disk size, and database flags based on your workload characteristics.
You’ve learned how to set up and manage Google Cloud SQL using Terraform. The practical path moves from a minimal development instance using db-f1-micro or g1-small, through private network configuration with PD_SSD and disk autoresize, to production hardening with deletion protection, password validation policy, Secret Manager integration, and regional high availability. Terraform version constraints, module upgrade guides, and explicit variable definitions keep the configuration maintainable across 26.X releases and beyond. The core resources remain consistent: Cloud SQL DB Instance, Cloud SQL Database, Cloud SQL User, Secret Manager Secret, and Secret Manager Secret Version, with ephemeral credentials for initial provisioning. Wrapping Up.