LAB21_GCP_Data Protection: Compute Engine Disk Snapshots

Data Protection: Compute Engine Disk Snapshots

☁ GCP 🟢 Beginner Compute Engine Persistent Disk Snapshot

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.

Your Objectives
  • 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"
✓ Expected Output After Apply
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