GCP for DevOps — Networking Exercises
Practice Exercises — Networking
Exercise 1 — Create a Custom VPC with Multi-Tier Subnets
Task: Create a custom VPC called exercise-vpc with three subnets (web, app, db) in us-central1 with Private Google Access enabled.
Show Answer
# Create the VPC
$ gcloud compute networks create exercise-vpc \
--subnet-mode=custom
# Create three subnets
$ gcloud compute networks subnets create web-subnet \
--network=exercise-vpc \
--region=us-central1 \
--range=10.1.1.0/24 \
--enable-private-ip-google-access
$ gcloud compute networks subnets create app-subnet \
--network=exercise-vpc \
--region=us-central1 \
--range=10.1.2.0/24 \
--enable-private-ip-google-access
$ gcloud compute networks subnets create db-subnet \
--network=exercise-vpc \
--region=us-central1 \
--range=10.1.3.0/24 \
--enable-private-ip-google-access
# Verify
$ gcloud compute networks subnets list --network=exercise-vpc \
--format="table(name,region,ipCidrRange,privateIpGoogleAccess)"
NAME REGION IP_CIDR_RANGE PRIVATE_IP_GOOGLE_ACCESS
app-subnet us-central1 10.1.2.0/24 True
db-subnet us-central1 10.1.3.0/24 True
web-subnet us-central1 10.1.1.0/24 True
Exercise 2 — Configure Three-Tier Firewall Rules
Task: Create firewall rules that allow: HTTP/HTTPS to web tier, web-to-app on port 8080, app-to-db on port 5432, and SSH via IAP only.
Show Answer
# Allow HTTP/HTTPS to web tier
$ gcloud compute firewall-rules create ex-allow-web-ingress \
--network=exercise-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:80,tcp:443 \
--source-ranges=0.0.0.0/0 \
--target-tags=web-tier \
--priority=1000
# Allow web → app on port 8080
$ gcloud compute firewall-rules create ex-allow-web-to-app \
--network=exercise-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:8080 \
--source-tags=web-tier \
--target-tags=app-tier \
--priority=1000
# Allow app → db on port 5432
$ gcloud compute firewall-rules create ex-allow-app-to-db \
--network=exercise-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:5432 \
--source-tags=app-tier \
--target-tags=db-tier \
--priority=1000
# Allow SSH via IAP
$ gcloud compute firewall-rules create ex-allow-iap-ssh \
--network=exercise-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:22 \
--source-ranges=35.235.240.0/20 \
--priority=1000
# Deny everything else
$ gcloud compute firewall-rules create ex-deny-all-ingress \
--network=exercise-vpc \
--direction=INGRESS \
--action=DENY \
--rules=all \
--source-ranges=0.0.0.0/0 \
--priority=65000
# Verify the rules
$ gcloud compute firewall-rules list --filter="network:exercise-vpc" \
--sort-by=priority \
--format="table(name,direction,priority,allowed[].map().firewall_rule().list():label=ALLOWED)"
Exercise 3 — Set Up Cloud NAT
Task: Create a Cloud NAT gateway for the exercise-vpc so private VMs can reach the internet.
Show Answer
# Create a Cloud Router
$ gcloud compute routers create ex-router \
--network=exercise-vpc \
--region=us-central1
# Create Cloud NAT with auto-allocated IPs
$ gcloud compute routers nats create ex-nat \
--router=ex-router \
--region=us-central1 \
--nat-all-subnet-ip-ranges \
--auto-allocate-nat-external-ips \
--enable-logging \
--log-filter=ERRORS_ONLY
# Verify
$ gcloud compute routers nats describe ex-nat \
--router=ex-router \
--region=us-central1
# Test: create a private VM and verify it can reach the internet
$ gcloud compute instances create nat-test \
--zone=us-central1-a \
--machine-type=e2-micro \
--network=exercise-vpc \
--subnet=app-subnet \
--no-address \
--image-family=debian-12 \
--image-project=debian-cloud
$ gcloud compute ssh nat-test --zone=us-central1-a --tunnel-through-iap
# Inside the VM:
$ curl -s https://ifconfig.me
# Should show the NAT gateway IP, not a VM IP
$ exit
Exercise 4 — Create an HTTP Load Balancer
Task: Set up a global HTTP load balancer that distributes traffic to a MIG.
Show Answer
# Step 1: Create an instance template
$ gcloud compute instance-templates create ex-web-template \
--machine-type=e2-small \
--image-family=debian-12 \
--image-project=debian-cloud \
--network=exercise-vpc \
--subnet=web-subnet \
--tags=web-tier,health-check \
--no-address \
--metadata=startup-script='#!/bin/bash
apt-get update && apt-get install -y nginx
echo "Hello from $(hostname)" > /var/www/html/index.html
echo "OK" > /var/www/html/health
'
# Step 2: Create a MIG
$ gcloud compute instance-groups managed create ex-web-mig \
--zone=us-central1-a \
--template=ex-web-template \
--size=2
# Set named ports
$ gcloud compute instance-groups set-named-ports ex-web-mig \
--zone=us-central1-a \
--named-ports=http:80
# Step 3: Allow health checks
$ gcloud compute firewall-rules create ex-allow-health-check \
--network=exercise-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:80 \
--source-ranges=130.211.0.0/22,35.191.0.0/16 \
--target-tags=health-check \
--priority=1000
# Step 4: Create health check
$ gcloud compute health-checks create http ex-web-hc \
--port=80 --request-path=/health
# Step 5: Create backend service
$ gcloud compute backend-services create ex-web-backend \
--protocol=HTTP --port-name=http \
--health-checks=ex-web-hc --global
# Step 6: Add backend
$ gcloud compute backend-services add-backend ex-web-backend \
--instance-group=ex-web-mig \
--instance-group-zone=us-central1-a \
--global
# Step 7: Create URL map
$ gcloud compute url-maps create ex-url-map \
--default-service=ex-web-backend
# Step 8: Create proxy and forwarding rule
$ gcloud compute target-http-proxies create ex-http-proxy \
--url-map=ex-url-map
$ gcloud compute forwarding-rules create ex-http-rule \
--global --target-http-proxy=ex-http-proxy --ports=80
# Step 9: Test
$ LB_IP=$(gcloud compute forwarding-rules describe ex-http-rule \
--global --format="get(IPAddress)")
$ echo "Load balancer IP: $LB_IP"
$ curl http://$LB_IP
Exercise 5 — VPC Peering
Task: Create two VPCs and establish VPC peering between them. Verify connectivity.
Show Answer
# Create VPC-1
$ gcloud compute networks create vpc-1 --subnet-mode=custom
$ gcloud compute networks subnets create vpc1-subnet \
--network=vpc-1 --region=us-central1 --range=10.10.0.0/24
# Create VPC-2
$ gcloud compute networks create vpc-2 --subnet-mode=custom
$ gcloud compute networks subnets create vpc2-subnet \
--network=vpc-2 --region=us-central1 --range=10.20.0.0/24
# Create peering (both directions)
$ gcloud compute networks peerings create peer-1-to-2 \
--network=vpc-1 --peer-network=vpc-2
$ gcloud compute networks peerings create peer-2-to-1 \
--network=vpc-2 --peer-network=vpc-1
# Verify peering is active
$ gcloud compute networks peerings list --network=vpc-1
NAME NETWORK PEER_NETWORK STATE
peer-1-to-2 vpc-1 vpc-2 ACTIVE
# Create VMs in each VPC to test connectivity
$ gcloud compute firewall-rules create vpc1-allow-internal \
--network=vpc-1 --action=ALLOW --rules=icmp,tcp:22 \
--source-ranges=10.10.0.0/24,10.20.0.0/24
$ gcloud compute firewall-rules create vpc2-allow-internal \
--network=vpc-2 --action=ALLOW --rules=icmp,tcp:22 \
--source-ranges=10.10.0.0/24,10.20.0.0/24
$ gcloud compute instances create vm-in-vpc1 \
--zone=us-central1-a --network=vpc-1 --subnet=vpc1-subnet \
--machine-type=e2-micro --image-family=debian-12 --image-project=debian-cloud
$ gcloud compute instances create vm-in-vpc2 \
--zone=us-central1-a --network=vpc-2 --subnet=vpc2-subnet \
--machine-type=e2-micro --image-family=debian-12 --image-project=debian-cloud
# Test: ping from vpc-1 to vpc-2
$ gcloud compute ssh vm-in-vpc1 --zone=us-central1-a
$ ping -c 3 10.20.0.2 # IP of vm-in-vpc2
PING 10.20.0.2: 3 packets transmitted, 3 received, 0% packet loss
Cleanup
$ gcloud compute instances delete nat-test vm-in-vpc1 vm-in-vpc2 --zone=us-central1-a --quiet
$ gcloud compute instance-groups managed delete ex-web-mig --zone=us-central1-a --quiet
$ gcloud compute instance-templates delete ex-web-template --quiet
$ gcloud compute forwarding-rules delete ex-http-rule --global --quiet
$ gcloud compute target-http-proxies delete ex-http-proxy --quiet
$ gcloud compute url-maps delete ex-url-map --quiet
$ gcloud compute backend-services delete ex-web-backend --global --quiet
$ gcloud compute health-checks delete ex-web-hc --quiet
$ gcloud compute routers nats delete ex-nat --router=ex-router --region=us-central1 --quiet
$ gcloud compute routers delete ex-router --region=us-central1 --quiet
$ gcloud compute firewall-rules delete ex-allow-web-ingress ex-allow-web-to-app ex-allow-app-to-db ex-allow-iap-ssh ex-deny-all-ingress ex-allow-health-check vpc1-allow-internal vpc2-allow-internal --quiet
$ gcloud compute networks peerings delete peer-1-to-2 --network=vpc-1 --quiet
$ gcloud compute networks peerings delete peer-2-to-1 --network=vpc-2 --quiet
$ gcloud compute networks subnets delete web-subnet app-subnet db-subnet vpc1-subnet vpc2-subnet --region=us-central1 --quiet
$ gcloud compute networks delete exercise-vpc vpc-1 vpc-2 --quiet
Next Chapter → Storage