GCP for DevOps — Networking Exercises

5 minute read

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

Updated: