GCP for DevOps — Compute Engine Basics

3 minute read

Compute Engine Basics

Compute Engine lets you create and run virtual machines on Google’s infrastructure. Each VM runs in a specific zone, belongs to a project, and is connected to a VPC network.

Creating a VM Instance

# Create a basic VM
$ gcloud compute instances create my-vm \
    --zone=us-central1-a \
    --machine-type=e2-medium \
    --image-family=debian-12 \
    --image-project=debian-cloud \
    --boot-disk-size=20GB \
    --tags=http-server

Created [https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/my-vm].
NAME   ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
my-vm  us-central1-a  e2-medium                  10.128.0.2   34.68.123.45  RUNNING
# Create a VM with a specific service account and no external IP
$ gcloud compute instances create build-agent \
    --zone=us-central1-a \
    --machine-type=e2-standard-4 \
    --image-family=ubuntu-2204-lts \
    --image-project=ubuntu-os-cloud \
    --boot-disk-size=50GB \
    --boot-disk-type=pd-ssd \
    --no-address \
    --service-account=ci-deployer@my-project.iam.gserviceaccount.com \
    --scopes=cloud-platform \
    --metadata=enable-oslogin=TRUE

Created [https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/build-agent].
NAME         ZONE           MACHINE_TYPE    INTERNAL_IP  EXTERNAL_IP  STATUS
build-agent  us-central1-a  e2-standard-4   10.128.0.3                RUNNING

Listing and Describing Instances

# List all instances in the project
$ gcloud compute instances list

NAME         ZONE           MACHINE_TYPE    PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
build-agent  us-central1-a  e2-standard-4                10.128.0.3                  RUNNING
my-vm        us-central1-a  e2-medium                    10.128.0.2   34.68.123.45  RUNNING

# Describe a specific instance
$ gcloud compute instances describe my-vm --zone=us-central1-a \
    --format="yaml(name,machineType,status,networkInterfaces[0].networkIP)"

machineType: zones/us-central1-a/machineTypes/e2-medium
name: my-vm
networkInterfaces:
- networkIP: 10.128.0.2
status: RUNNING

SSH Access

# SSH using gcloud (uses OS Login or project metadata keys)
$ gcloud compute ssh my-vm --zone=us-central1-a

# SSH with OS Login (recommended)
$ gcloud compute ssh my-vm --zone=us-central1-a

# SSH to a VM without external IP (via IAP tunnel)
$ gcloud compute ssh build-agent --zone=us-central1-a --tunnel-through-iap

# SSH with a specific user
$ gcloud compute ssh user@my-vm --zone=us-central1-a

# Run a command remotely via SSH
$ gcloud compute ssh my-vm --zone=us-central1-a --command="uname -a"

Linux my-vm 6.1.0-18-cloud-amd64 #1 SMP x86_64 GNU/Linux

OS Login

OS Login links SSH access to IAM — no need to manage SSH keys manually.

# Enable OS Login at the project level
$ gcloud compute project-info add-metadata \
    --metadata=enable-oslogin=TRUE

# Grant SSH access via IAM
$ gcloud projects add-iam-policy-binding my-project \
    --member="user:dev@example.com" \
    --role="roles/compute.osLogin"

# For root/sudo access
$ gcloud projects add-iam-policy-binding my-project \
    --member="user:admin@example.com" \
    --role="roles/compute.osAdminLogin"

Managing VM Lifecycle

# Stop a VM (keeps the disk, stops billing for compute)
$ gcloud compute instances stop my-vm --zone=us-central1-a

Stopping instance(s) my-vm...done.

# Start a stopped VM
$ gcloud compute instances start my-vm --zone=us-central1-a

Starting instance(s) my-vm...done.

# Reset a VM (hard reboot)
$ gcloud compute instances reset my-vm --zone=us-central1-a

# Suspend a VM (saves memory state)
$ gcloud compute instances suspend my-vm --zone=us-central1-a

# Resume a suspended VM
$ gcloud compute instances resume my-vm --zone=us-central1-a

# Delete a VM
$ gcloud compute instances delete my-vm --zone=us-central1-a --quiet

Deleted [my-vm].

Labels and Metadata

# Add labels (for billing, organization)
$ gcloud compute instances add-labels my-vm \
    --zone=us-central1-a \
    --labels=env=dev,team=devops,cost-center=engineering

# Set custom metadata (key-value pairs available inside the VM)
$ gcloud compute instances add-metadata my-vm \
    --zone=us-central1-a \
    --metadata=app-version=2.1.0,config-url=gs://my-bucket/config.json

# Read metadata from inside the VM
$ curl -H "Metadata-Flavor: Google" \
    http://metadata.google.internal/computeMetadata/v1/instance/attributes/app-version

2.1.0

Preemptible and Spot VMs

Preemptible and Spot VMs are heavily discounted (60–91% off) but can be terminated by GCE at any time.

# Create a Spot VM (replacement for preemptible)
$ gcloud compute instances create batch-worker \
    --zone=us-central1-a \
    --machine-type=e2-standard-8 \
    --provisioning-model=SPOT \
    --instance-termination-action=STOP \
    --image-family=debian-12 \
    --image-project=debian-cloud

# Create a preemptible VM (legacy, max 24 hours)
$ gcloud compute instances create batch-worker-legacy \
    --zone=us-central1-a \
    --machine-type=e2-standard-8 \
    --preemptible \
    --image-family=debian-12 \
    --image-project=debian-cloud
Feature Standard VM Preemptible VM Spot VM
Max lifetime Unlimited 24 hours Unlimited
Discount 0% 60–91% 60–91%
Termination User-initiated GCE can preempt GCE can preempt
SLA Yes No No
Use case Production Batch, CI/CD Batch, CI/CD, fault-tolerant

Common Mistakes

Mistake Why It’s Wrong Fix
Using default SA Has roles/editor — too broad Create dedicated SA per VM
Always using e2-medium May be over/under-provisioned Right-size with Recommender
Not using --no-address VM gets public IP unnecessarily Use IAP or Cloud NAT
Forgetting to set zone Defaults may not be what you expect Always specify --zone
Not adding labels Hard to track cost and ownership Label everything: env, team, app

Quick Reference

Command Description
gcloud compute instances create NAME Create a VM
gcloud compute instances list List all VMs
gcloud compute instances describe NAME --zone=ZONE Show VM details
gcloud compute ssh NAME --zone=ZONE SSH into a VM
gcloud compute instances stop NAME --zone=ZONE Stop a VM
gcloud compute instances start NAME --zone=ZONE Start a VM
gcloud compute instances delete NAME --zone=ZONE Delete a VM
gcloud compute instances add-labels NAME --labels=K=V Add labels

Next → Machine Types & Images

Updated: