Happy Dussehra! May good always win. Happy Diwali! Wishing you a bright year ahead. Merry Christmas! Warm wishes from Vizag. Happy New Year! Here’s to a great year ahead.

Archive · GCP

GCP Basics: Compute Engine, VPC and Cloud Storage

Build a private network with IAP access and Cloud NAT, run VMs in a managed instance group, and use Cloud Storage safely, with the differences from AWS.

3 min read

  • Compute Engine
  • VPC
  • Cloud NAT
  • Identity-Aware Proxy
  • Cloud Storage

This post builds a small but realistic network: private VMs with no public addresses, administered through Identity-Aware Proxy, reaching the internet through Cloud NAT, serving traffic behind a load balancer, with a locked-down Cloud Storage bucket.

Architecture

flowchart TB
  U[Users] --> LB[External Application Load Balancer<br/>global anycast IP]
  ADM[Admin] -->|SSH through IAP| MIG
  subgraph VPC[VPC app-vpc custom mode]
    subgraph SUB[Subnet app-mumbai 10.30.0.0/24]
      MIG[Managed instance group<br/>VMs across asia-south1 zones]
    end
    NAT[Cloud Router and Cloud NAT]
  end
  LB --> MIG
  MIG --> NAT --> NET[Internet for updates]
  MIG --> GCS[Cloud Storage bucket<br/>via Private Google Access]

VPC

A GCP VPC is global; subnets are regional, so one network spans regions without peering. Firewall rules apply to the whole network and match by network tag or, better, by service account. Every VPC has implied rules: deny all ingress and allow all egress.

gcloud compute networks create app-vpc --subnet-mode=custom
gcloud compute networks subnets create app-mumbai --network=app-vpc \
  --region=asia-south1 --range=10.30.0.0/24 --enable-private-ip-google-access
gcloud compute firewall-rules create allow-ssh-iap --network=app-vpc \
  --allow=tcp:22 --source-ranges=35.235.240.0/20
gcloud compute firewall-rules create allow-lb-health --network=app-vpc \
  --allow=tcp:8080 --source-ranges=130.211.0.0/22,35.191.0.0/16 --target-tags=web

35.235.240.0/20 is the range used by Identity-Aware Proxy for TCP forwarding, which lets you SSH without a public IP. The second rule allows Google’s load balancer health checkers. Users need roles/iap.tunnelResourceAccessor to use the tunnel.

Private VMs still need to download updates, which needs Cloud NAT:

gcloud compute routers create nat-router --network=app-vpc --region=asia-south1
gcloud compute routers nats create app-nat --router=nat-router --region=asia-south1 \
  --auto-allocate-nat-external-ips --nat-all-subnet-ip-ranges

Compute Engine

Start with a single VM to test the network:

gcloud compute instances create vm-demo --zone=asia-south1-a \
  --machine-type=e2-small --subnet=app-mumbai --no-address --tags=web \
  --image-family=ubuntu-2404-lts-amd64 --image-project=ubuntu-os-cloud \
  --metadata=enable-oslogin=TRUE --shielded-secure-boot
gcloud compute ssh vm-demo --zone=asia-south1-a --tunnel-through-iap

OS Login ties SSH access to IAM (roles/compute.osLogin) instead of keys copied into metadata. For production, do not run pet VMs: create an instance template and a managed instance group that heals and scales:

gcloud compute instance-templates create web-tpl --machine-type=e2-small --subnet=app-mumbai \
  --region=asia-south1 --no-address --tags=web --image-family=ubuntu-2404-lts-amd64 \
  --image-project=ubuntu-os-cloud --metadata-from-file=startup-script=startup.sh
gcloud compute health-checks create http web-hc --port=8080 --request-path=/healthz
gcloud compute instance-groups managed create web-mig --region=asia-south1 \
  --template=web-tpl --size=2 \
  --health-check=web-hc --initial-delay=120
gcloud compute instance-groups managed set-autoscaling web-mig --region=asia-south1 \
  --min-num-replicas=2 --max-num-replicas=6 --target-cpu-utilization=0.6

A regional group spreads instances across zones. Attach it to an external Application Load Balancer through a backend service, with a managed certificate for HTTPS. Compared with AWS: a GCP load balancer uses one global anycast IP, and a backend service plays the part of the target group.

Cloud Storage

gcloud storage buckets create gs://demo-ci-2025-assets --location=asia-south1 \
  --uniform-bucket-level-access --public-access-prevention
gcloud storage cp backup.tar.gz gs://demo-ci-2025-assets/
gcloud storage buckets update gs://demo-ci-2025-assets --versioning
  • Uniform bucket-level access turns off per-object ACLs, so IAM alone decides who can read, and public access prevention blocks anything from being made public by mistake.
  • New buckets also have soft delete with a seven-day default retention, which allows recovery of deleted objects (and is billed as storage while it holds them).
  • Add lifecycle rules to move old objects to cheaper classes or delete them, and consider Autoclass when access patterns are unknown.
  • VMs and the group reach the bucket through Private Google Access without public IPs; grant the VM’s service account roles/storage.objectUser on this bucket only.

Cost hygiene

Delete test VMs and unattached disks when finished. Stopped VMs still bill for their disks and reserved external addresses, and Cloud NAT and load balancers bill by the hour. Label every resource with owner and environment, and set a budget alert (see the previous post).