GCP for DevOps — Cost Optimization Exercises

3 minute read

Practice Exercises — Cost Optimization

Exercise 1: Set Up Budget Alerts

Create a budget with alert thresholds for a project.

  1. Enable the billing budgets API
  2. Create a Pub/Sub topic for billing alerts
  3. Configure a budget of $100/month with alerts at 50%, 75%, and 100%
  4. Verify the budget is created
Show Answer
# Enable the API
$ gcloud services enable billingbudgets.googleapis.com

# Create Pub/Sub topic
$ gcloud pubsub topics create billing-alerts

# Create the budget (via Console or API)
# Console: Billing → Budgets & alerts → Create Budget
# Set amount: $100
# Set thresholds: 50%, 75%, 100%
# Set notification channel: billing-alerts topic

# Verify
$ gcloud pubsub topics list | grep billing-alerts
name: projects/my-project/topics/billing-alerts

Exercise 2: Find and Clean Up Idle Resources

Identify idle VMs, unattached disks, and unused static IPs.

  1. List all VM rightsizing recommendations
  2. Find unattached persistent disks
  3. Find unused static IP addresses
  4. Calculate potential monthly savings
Show Answer
# List VM recommendations
$ gcloud recommender recommendations list \
    --project=my-project \
    --location=us-central1-a \
    --recommender=google.compute.instance.IdleResourceRecommender

# Find unattached disks
$ gcloud compute disks list \
    --filter="NOT users:*" \
    --format="table(name,zone,sizeGb,type)"

# Find unused static IPs ($7.30/month each)
$ gcloud compute addresses list \
    --filter="status=RESERVED" \
    --format="table(name,region,address)"

# Clean up
$ gcloud compute disks delete DISK_NAME --zone=ZONE --quiet
$ gcloud compute addresses delete IP_NAME --region=REGION --quiet

Exercise 3: Create a Spot VM Pool for CI/CD

Set up a managed instance group using Spot VMs for CI/CD build agents.

  1. Create an instance template with Spot provisioning
  2. Create a managed instance group with 3 Spot instances
  3. Enable autoscaling between 1 and 10 instances
  4. Compare the cost with regular VMs
Show Answer
# Create Spot instance template
$ gcloud compute instance-templates create ci-spot-template \
    --machine-type=e2-standard-4 \
    --provisioning-model=SPOT \
    --instance-termination-action=DELETE \
    --image-family=debian-12 \
    --image-project=debian-cloud \
    --boot-disk-size=50GB \
    --metadata=startup-script='#!/bin/bash
      apt-get update && apt-get install -y docker.io
      systemctl start docker'

# Create MIG
$ gcloud compute instance-groups managed create ci-build-pool \
    --zone=us-central1-a \
    --template=ci-spot-template \
    --size=3

# Enable autoscaling
$ gcloud compute instance-groups managed set-autoscaling ci-build-pool \
    --zone=us-central1-a \
    --min-num-replicas=1 \
    --max-num-replicas=10 \
    --target-cpu-utilization=0.7

# Cost comparison (e2-standard-4):
# On-demand: ~$97/month × 3 = $291/month
# Spot:      ~$29/month × 3 = $87/month
# Savings:   ~$204/month (70% reduction)

Exercise 4: Set Up Cloud Storage Lifecycle Policies

Configure lifecycle rules to automatically move objects to cheaper storage classes.

  1. Create a storage bucket
  2. Apply lifecycle rules: Nearline after 30 days, Coldline after 90 days, delete after 365 days
  3. Verify the lifecycle configuration
Show Answer
# Create bucket
$ gcloud storage buckets create gs://my-data-lifecycle-demo \
    --location=us-central1 \
    --default-storage-class=STANDARD

# Create lifecycle rules file
$ cat > lifecycle.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {"type": "SetStorageClass", "storageClass": "NEARLINE"},
        "condition": {"age": 30, "matchesStorageClass": ["STANDARD"]}
      },
      {
        "action": {"type": "SetStorageClass", "storageClass": "COLDLINE"},
        "condition": {"age": 90, "matchesStorageClass": ["NEARLINE"]}
      },
      {
        "action": {"type": "Delete"},
        "condition": {"age": 365}
      }
    ]
  }
}
EOF

# Apply lifecycle rules
$ gcloud storage buckets update gs://my-data-lifecycle-demo \
    --lifecycle-file=lifecycle.json

# Verify
$ gcloud storage buckets describe gs://my-data-lifecycle-demo \
    --format="json(lifecycle)"

# Cleanup
$ gcloud storage rm -r gs://my-data-lifecycle-demo

Exercise 5: Query Billing Data in BigQuery

Write BigQuery SQL queries to analyze costs by service, project, and label.

  1. Write a query for top 5 most expensive services this month
  2. Write a query for daily cost trend (last 7 days)
  3. Write a query to find cost by team label
Show Answer
-- Top 5 most expensive services this month
SELECT
  service.description AS service,
  ROUND(SUM(cost), 2) AS total_cost
FROM `billing_data.gcp_billing_export_v1_XXXXX`
WHERE invoice.month = FORMAT_DATE('%Y%m', CURRENT_DATE())
GROUP BY service
ORDER BY total_cost DESC
LIMIT 5;

-- Daily cost trend (last 7 days)
SELECT
  DATE(usage_start_time) AS date,
  ROUND(SUM(cost), 2) AS daily_cost
FROM `billing_data.gcp_billing_export_v1_XXXXX`
WHERE usage_start_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY date
ORDER BY date DESC;

-- Cost by team label
SELECT
  (SELECT value FROM UNNEST(labels) WHERE key = 'team') AS team,
  ROUND(SUM(cost), 2) AS total_cost
FROM `billing_data.gcp_billing_export_v1_XXXXX`
WHERE invoice.month = FORMAT_DATE('%Y%m', CURRENT_DATE())
GROUP BY team
HAVING team IS NOT NULL
ORDER BY total_cost DESC;

Cleanup

# Delete Spot instance group
$ gcloud compute instance-groups managed delete ci-build-pool \
    --zone=us-central1-a --quiet

# Delete instance template
$ gcloud compute instance-templates delete ci-spot-template --quiet

# Delete lifecycle demo bucket
$ gcloud storage rm -r gs://my-data-lifecycle-demo

# Delete Pub/Sub topic
$ gcloud pubsub topics delete billing-alerts

Next Chapter → Practice Projects

Updated: