Managing Cloud Spanner with Terraform
Learn how to set up and manage Google Cloud Spanner using Terraform
In this guide, we’ll explore how to manage Google Cloud Spanner using Terraform.
Video Tutorial
Learn more about managing Google Cloud Spanner with Terraform in this comprehensive video tutorial:
Prerequisites
- Google Cloud SDK installed and configured
- Terraform installed (version 1.0.0 or later)
- A GCP project with billing enabled
Provider Configuration
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 4.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
Variables
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 Spanner instance"
type = string
}
variable "database_name" {
description = "Name of the Spanner database"
type = string
}
Instance Configuration
resource "google_spanner_instance" "main" {
name = var.instance_name
config = "regional-${var.region}"
display_name = "Main Spanner Instance"
num_nodes = 1
labels = {
environment = "production"
}
}
resource "google_spanner_database" "database" {
instance = google_spanner_instance.main.name
name = var.database_name
ddl = [
"CREATE TABLE users (user_id STRING(36) NOT NULL, name STRING(MAX), email STRING(MAX)) PRIMARY KEY (user_id)",
"CREATE TABLE orders (order_id STRING(36) NOT NULL, user_id STRING(36) NOT NULL, amount FLOAT64, status STRING(MAX)) PRIMARY KEY (order_id)",
"CREATE INDEX UserOrdersByAmount ON orders(user_id, amount DESC)",
]
deletion_protection = true
}
IAM Configuration
resource "google_spanner_database_iam_binding" "database" {
instance = google_spanner_instance.main.name
database = google_spanner_database.database.name
role = "roles/spanner.databaseUser"
members = [
"serviceAccount:${google_service_account.spanner_user.email}",
]
}
resource "google_service_account" "spanner_user" {
account_id = "spanner-user"
display_name = "Spanner User Service Account"
}
resource "google_project_iam_member" "spanner_viewer" {
project = var.project_id
role = "roles/spanner.viewer"
member = "serviceAccount:${google_service_account.spanner_user.email}"
}
Backup Configuration
resource "google_spanner_backup" "backup" {
instance = google_spanner_instance.main.name
database = google_spanner_database.database.name
backup = "${var.database_name}-backup"
expiration_seconds = 7 * 24 * 60 * 60 # 7 days
lifecycle {
prevent_destroy = true
}
}
Instance Configuration with High Availability
resource "google_spanner_instance" "ha_instance" {
name = "${var.instance_name}-ha"
config = "regional-${var.region}"
display_name = "HA Spanner Instance"
num_nodes = 3 # Minimum for high availability
labels = {
environment = "production"
ha = "true"
}
}
resource "google_spanner_database" "ha_database" {
instance = google_spanner_instance.ha_instance.name
name = "${var.database_name}-ha"
version_retention_period = "7d" # Keep 7 days of version history
ddl = [
"CREATE TABLE users (user_id STRING(36) NOT NULL, name STRING(MAX), email STRING(MAX)) PRIMARY KEY (user_id)",
"CREATE TABLE orders (order_id STRING(36) NOT NULL, user_id STRING(36) NOT NULL, amount FLOAT64, status STRING(MAX)) PRIMARY KEY (order_id)",
"CREATE INDEX UserOrdersByAmount ON orders(user_id, amount DESC)",
]
deletion_protection = true
encryption_config {
kms_key_name = google_kms_crypto_key.spanner_key.id
}
}
Monitoring Configuration
resource "google_monitoring_alert_policy" "spanner_cpu" {
display_name = "Spanner CPU Usage Alert"
combiner = "OR"
conditions {
display_name = "High CPU Usage"
condition_threshold {
filter = "metric.type=\"spanner.googleapis.com/instance/cpu/utilization\" AND resource.type=\"spanner_instance\""
duration = "300s"
comparison = "COMPARISON_GT"
threshold_value = 0.8
trigger {
count = 1
}
aggregations {
alignment_period = "60s"
per_series_aligner = "ALIGN_MEAN"
}
}
}
notification_channels = [google_monitoring_notification_channel.email.name]
}
Outputs
output "instance_id" {
value = google_spanner_instance.main.id
description = "The ID of the Spanner instance"
}
output "database_id" {
value = google_spanner_database.database.id
description = "The ID of the Spanner database"
}
output "instance_state" {
value = google_spanner_instance.main.state
description = "The current state of the Spanner instance"
}
Best Practices
-
Instance Management:
- Right-size nodes
- Enable high availability
- Configure backups
- Monitor performance
-
Security:
- Use IAM roles
- Enable encryption
- Regular audits
- Secure connections
-
Performance:
- Optimize schemas
- Monitor metrics
- Use indexes
- Regular maintenance
-
Cost Optimization:
- Monitor usage
- Right-size instances
- Clean up unused
- Regular review
Common Operations
Creating Resources
terraform init
terraform plan
terraform apply
Database Operations
# Create backup
gcloud spanner backups create backup-name \
--instance=instance-name \
--database=database-name
# List backups
gcloud spanner backups list --instance=instance-name
Best Practices and Tips
-
Schema Management:
- Plan carefully
- Use proper types
- Create indexes
- Regular review
-
Backup Strategy:
- Regular backups
- Test restores
- Monitor space
- Retention policy
-
Operations:
- Monitor performance
- Track metrics
- Set up alerts
- Regular maintenance
Conclusion
You’ve learned how to set up and manage Google Cloud Spanner using Terraform. This setup provides:
- Scalable database
- High availability
- Data consistency
- Best practices implementation