Data Protection: Compute Engine Disk Snapshots
Scenario
You have a standalone Compute Engine instance running legacy software that stores data directly on its boot disk. You need to create a point-in-time backup of this disk via a Snapshot to ensure the data can be recovered or migrated to a new instance later.
- Create a google_compute_disk resource as a standalone persistent disk.
- Create a google_compute_snapshot resource that takes a snapshot of that disk.
- Ensure the snapshot depends on the disk using implicit dependencies (source_disk = google_compute_disk.my_disk.id).
- Output the snapshot's ID and storage bytes.
Additional Context
Snapshot Schedules: While you can create single ad-hoc snapshots via Terraform (as demonstrated here), in a true production environment you would use a google_compute_resource_policy to define a backup schedule (e.g. daily at 2AM, keep for 14 days), and attach that policy to the disk.
Incremental nature: Compute Engine snapshots are incremental by default. The first snapshot is a full backup, but subsequent snapshots only store blocks that have modified since the previous snapshot, saving money.
variables.tf
variable "project_id" { type = string }
variable "gcp_zone" { type = string; default = "us-central1-a" }main.tf
provider "google" {
project = var.project_id
zone = var.gcp_zone
}
# 1. A standalone Persistent Disk
resource "google_compute_disk" "data_disk" {
name = "postgres-data-disk"
type = "pd-balanced"
size = 50 # 50 GB
# Base image is just to give it some data for the lab
image = "debian-cloud/debian-11"
labels = {
environment = "dev"
}
}
# 2. Add an explicit sleep to ensure the disk is fully ready before snapshotting
# (Usually not required, but sometimes GCP disk readiness lags slightly behind Terraform)
resource "time_sleep" "wait_for_disk" {
depends_on = [google_compute_disk.data_disk]
create_duration = "10s"
}
# 3. Create a point-in-time Snapshot of the disk
resource "google_compute_snapshot" "data_backup" {
name = "postgres-data-backup-initial"
source_disk = google_compute_disk.data_disk.id
# Store the snapshot in the multi-region covering the zone for better availability
storage_locations = ["us"]
labels = {
backup_type = "manual"
}
depends_on = [time_sleep.wait_for_disk]
}outputs.tf
output "snapshot_id" {
value = google_compute_snapshot.data_backup.id
}
output "snapshot_size_gb" {
value = google_compute_snapshot.data_backup.disk_size_gb
}Workflow Commands
terraform init
terraform apply -var="project_id=my-gcp-project-123"
# Verify the snapshot exists
gcloud compute snapshots describe postgres-data-backup-initial
terraform destroy -var="project_id=my-gcp-project-123"Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs: snapshot_id = "projects/my-gcp-project-123/global/snapshots/postgres-data-backup-initial" snapshot_size_gb = 50

