GCP for DevOps — Subnets & Firewall
Subnets & Firewall
Subnets define IP ranges within a region, and firewall rules control traffic flow. Together they form the network security foundation for your GCP infrastructure.
Subnet IP Planning
Production VPC: prod-vpc
│
├── us-central1
│ ├── prod-web: 10.1.1.0/24 (254 hosts)
│ ├── prod-app: 10.1.2.0/24 (254 hosts)
│ ├── prod-db: 10.1.3.0/24 (254 hosts)
│ └── gke-nodes: 10.1.10.0/24 (254 hosts)
│ ├── pods: 10.100.0.0/16 (65,534 pods)
│ └── services: 10.200.0.0/20 (4,094 services)
│
├── us-east1
│ ├── dr-web: 10.2.1.0/24
│ └── dr-app: 10.2.2.0/24
│
└── europe-west1
└── eu-app: 10.3.1.0/24
Expanding Subnets
Unlike many cloud providers, GCP subnets can be expanded (but not shrunk).
# Expand a subnet range
$ gcloud compute networks subnets expand-ip-range prod-web \
--region=us-central1 \
--prefix-length=22
Updated [prod-web].
# Range changed from 10.1.1.0/24 (254 IPs) to 10.1.0.0/22 (1,022 IPs)
Firewall Rule Architecture
┌─────────────────────────────────────────────────────┐
│ VPC: prod-vpc │
│ │
│ Firewall Rules (evaluated by priority): │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ P:100 DENY all → 198.51.100.0/24 │ │
│ │ P:1000 ALLOW tcp:80,443 → tag:web │ │
│ │ P:1000 ALLOW tcp:22 from 35.235.240.0/20 │ │
│ │ P:1000 ALLOW tcp:8080 tag:app → tag:app │ │
│ │ P:1100 ALLOW tcp:5432 SA:app → SA:db │ │
│ │ P:65534 ALLOW all from 10.0.0.0/8 (int) │ │
│ │ P:65535 DENY all ingress (implied) │ │
│ │ P:65535 ALLOW all egress (implied) │ │
│ └────────────────────────────────────────────┘ │
│ │
│ Traffic matching: First match wins (lowest P#) │
└─────────────────────────────────────────────────────┘
Three-Tier Firewall Example
# Web tier: allow HTTP/HTTPS from internet
$ gcloud compute firewall-rules create prod-allow-web \
--network=prod-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:80,tcp:443 \
--source-ranges=0.0.0.0/0 \
--target-tags=web-tier \
--priority=1000
# App tier: allow from web tier only
$ gcloud compute firewall-rules create prod-allow-web-to-app \
--network=prod-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:8080 \
--source-tags=web-tier \
--target-tags=app-tier \
--priority=1000
# DB tier: allow from app tier only (service account based)
$ gcloud compute firewall-rules create prod-allow-app-to-db \
--network=prod-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:5432 \
--source-service-accounts=app-sa@my-project.iam.gserviceaccount.com \
--target-service-accounts=db-sa@my-project.iam.gserviceaccount.com \
--priority=1000
# SSH via IAP only
$ gcloud compute firewall-rules create prod-allow-iap \
--network=prod-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:22 \
--source-ranges=35.235.240.0/20 \
--priority=1000
# Health checks from Google's health check ranges
$ gcloud compute firewall-rules create prod-allow-health-check \
--network=prod-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:80,tcp:8080 \
--source-ranges=130.211.0.0/22,35.191.0.0/16 \
--target-tags=health-check \
--priority=1000
# Deny all other ingress (explicit, for clarity)
$ gcloud compute firewall-rules create prod-deny-all \
--network=prod-vpc \
--direction=INGRESS \
--action=DENY \
--rules=all \
--source-ranges=0.0.0.0/0 \
--priority=65000
Hierarchical Firewall Policies
Organization-wide firewall policies that apply across all VPCs.
# Create an organization-level firewall policy
$ gcloud compute firewall-policies create \
--organization=123456789 \
--short-name=org-security-policy \
--description="Organization security policy"
# Add a rule to block known malicious IPs
$ gcloud compute firewall-policies rules create 100 \
--firewall-policy=org-security-policy \
--organization=123456789 \
--direction=INGRESS \
--action=deny \
--src-ip-ranges=198.51.100.0/24 \
--layer4-configs=all
# Associate with the organization
$ gcloud compute firewall-policies associations create \
--firewall-policy=org-security-policy \
--organization=123456789
Tags vs Service Accounts for Targeting
| Method | Security | Ease of Use | Recommendation |
|---|---|---|---|
| Network tags | ⚠️ Any user with setTags can add |
Easy | Dev/test only |
| Service accounts | ✅ Tied to IAM identity | More setup | Production |
Firewall Insights
# View firewall insights (overly permissive rules)
$ gcloud recommender insights list \
--project=my-project \
--insight-type=google.compute.firewall.Insight \
--location=global \
--format="table(content.overview.firewallRuleName,content.overview.insight)"
Common Mistakes
| Mistake | Why It’s Wrong | Fix |
|---|---|---|
Using 0.0.0.0/0 for SSH |
Exposes to the internet | Use IAP range 35.235.240.0/20 |
| Not planning IP ranges | Overlapping ranges block peering | Plan before creating subnets |
| Forgetting health check ranges | Load balancer health checks fail | Allow 130.211.0.0/22,35.191.0.0/16 |
| One large subnet for everything | No network segmentation | Use separate subnets per tier |
| Not using firewall logging | Can’t debug connectivity | Enable logging on key rules |
Quick Reference
| Command | Description |
|---|---|
gcloud compute networks subnets create NAME |
Create a subnet |
gcloud compute networks subnets expand-ip-range NAME |
Expand subnet |
gcloud compute firewall-rules create NAME |
Create firewall rule |
--source-ranges=CIDR |
Source IP range (ingress) |
--source-tags=TAG |
Source tag (ingress) |
--target-tags=TAG |
Target VMs by tag |
--source-service-accounts=SA |
Source by SA |
--target-service-accounts=SA |
Target by SA |
Next → Cloud NAT