Google Cloud Networking Deep Dive: VPC, Load Balancers, and CDN
GCP networking differs fundamentally from AWS and traditional data center networking. This guide covers GCP VPC architecture, subnet design, routing, Cloud Load Balancing tiers, Cloud CDN for global content delivery, and hybrid connectivity with Cloud Interconnect and VPN.
GCP networking behaves differently from AWS and traditional data centers in ways that surprise engineers new to the platform. GCP VPCs are global — a single VPC spans all regions, unlike AWS where VPCs are region-scoped. Subnets are regional and each subnet spans all zones in a region. Firewall rules apply to instances based on network tags or service accounts, not security group membership.
Understanding these differences is important because networking decisions are foundational — they're hard to change after the fact without downtime.
GCP VPC Architecture
In AWS, a VPC is created in a specific region. To connect workloads in multiple regions, you create multiple VPCs and peer them or route through Transit Gateway.
In GCP, a VPC is a global resource. A single VPC can have subnets in any region, and instances in different regions within the same VPC can communicate using internal IP addresses. No VPC peering is needed for same-organization, different-region communication.
# Terraform: Single global VPC with subnets in multiple regions
resource "google_compute_network" "main" {
name = "production-vpc"
auto_create_subnetworks = false # Always use custom subnets
routing_mode = "GLOBAL" # Enables dynamic routing between regions
project = var.project_id
}
# Europe subnet
resource "google_compute_subnetwork" "europe_west4" {
name = "prod-subnet-europe-west4"
network = google_compute_network.main.id
region = "europe-west4"
ip_cidr_range = "10.0.0.0/20" # 4094 usable addresses
project = var.project_id
private_ip_google_access = true # Access GCP APIs without public IP
secondary_ip_range {
range_name = "gke-pods"
ip_cidr_range = "10.16.0.0/14" # 262144 pod addresses for GKE
}
secondary_ip_range {
range_name = "gke-services"
ip_cidr_range = "10.20.0.0/20" # 4094 service addresses for GKE
}
log_config {
aggregation_interval = "INTERVAL_10_MIN"
flow_sampling = 0.5 # Sample 50% of flows for VPC Flow Logs
metadata = "INCLUDE_ALL_METADATA"
}
}
# US subnet
resource "google_compute_subnetwork" "us_central1" {
name = "prod-subnet-us-central1"
network = google_compute_network.main.id
region = "us-central1"
ip_cidr_range = "10.1.0.0/20"
project = var.project_id
private_ip_google_access = true
}
Firewall Rules: Tags vs Service Accounts
GCP firewall rules use network tags or service accounts to identify targets — not instance groups or security groups like AWS.
# Allow HTTPS traffic to web servers (tagged with "web-server")
resource "google_compute_firewall" "allow_https" {
name = "allow-https-to-web"
network = google_compute_network.main.id
project = var.project_id
allow {
protocol = "tcp"
ports = ["443"]
}
target_tags = ["web-server"] # Applies to VMs with this tag
source_ranges = ["0.0.0.0/0"]
}
# Allow internal traffic from app tier to database tier
resource "google_compute_firewall" "app_to_db" {
name = "allow-app-to-db"
network = google_compute_network.main.id
project = var.project_id
allow {
protocol = "tcp"
ports = ["5432"]
}
# Service account-based rules are more secure than tags (tags can be changed by users)
target_service_accounts = ["database-sa@my-project.iam.gserviceaccount.com"]
source_service_accounts = ["app-sa@my-project.iam.gserviceaccount.com"]
}
# Default deny egress (explicit allow-list approach)
resource "google_compute_firewall" "deny_all_egress" {
name = "deny-all-egress"
network = google_compute_network.main.id
project = var.project_id
priority = 65534
deny {
protocol = "all"
}
direction = "EGRESS"
destination_ranges = ["0.0.0.0/0"]
}
Cloud Load Balancing Tiers
GCP has multiple load balancer types for different use cases:
| Type | Use Case | Backend Types | Protocol |
|---|---|---|---|
| Global External HTTPS | Internet-facing apps, global | GCE, GKE, Cloud Run, NEGs | HTTP/HTTPS, HTTP/2 |
| Regional External HTTPS | Region-specific internet apps | GCE, GKE NEGs | HTTP/HTTPS |
| Global External TCP | Non-HTTP internet traffic | GCE MIGs | TCP/UDP |
| Internal HTTP(S) | Microservices within VPC | GCE, GKE, Cloud Run | HTTP/HTTPS |
| Internal TCP/UDP | Internal TCP traffic | GCE MIGs | TCP/UDP |
Global HTTPS Load Balancer (Most Common)
# Global HTTPS Load Balancer with Cloud Armor and CDN
resource "google_compute_global_address" "lb_ip" {
name = "my-app-ip"
project = var.project_id
}
resource "google_compute_backend_service" "app" {
name = "app-backend"
project = var.project_id
protocol = "HTTPS"
port_name = "https"
timeout_sec = 30
enable_cdn = true
load_balancing_scheme = "EXTERNAL_MANAGED"
backend {
group = var.instance_group_url
balancing_mode = "UTILIZATION"
max_utilization = 0.8
}
health_checks = [google_compute_health_check.app.id]
# Attach Cloud Armor security policy
security_policy = google_compute_security_policy.waf.id
cdn_policy {
cache_mode = "CACHE_ALL_STATIC"
default_ttl = 3600
max_ttl = 86400
negative_caching = true
cache_key_policy {
include_host = true
include_protocol = true
include_query_string = false # Exclude query strings from cache key for static content
}
}
log_config {
enable = true
sample_rate = 1.0 # Log all requests
}
}
resource "google_compute_health_check" "app" {
name = "app-health-check"
project = var.project_id
check_interval_sec = 10
timeout_sec = 5
healthy_threshold = 2
unhealthy_threshold = 3
https_health_check {
port = 443
request_path = "/health"
}
}
resource "google_compute_url_map" "app" {
name = "app-url-map"
project = var.project_id
default_service = google_compute_backend_service.app.id
}
resource "google_compute_target_https_proxy" "app" {
name = "app-https-proxy"
project = var.project_id
url_map = google_compute_url_map.app.id
ssl_certificates = [google_compute_managed_ssl_certificate.app.id]
}
resource "google_compute_managed_ssl_certificate" "app" {
name = "app-ssl-cert"
project = var.project_id
managed {
domains = ["app.company.com", "www.company.com"]
}
}
resource "google_compute_global_forwarding_rule" "app_https" {
name = "app-https-rule"
project = var.project_id
target = google_compute_target_https_proxy.app.id
port_range = "443"
ip_address = google_compute_global_address.lb_ip.id
load_balancing_scheme = "EXTERNAL_MANAGED"
}
Cloud CDN Configuration
Cloud CDN caches responses at Google's 100+ edge locations globally:
# Enable CDN on an existing backend service
gcloud compute backend-services update my-backend --global --enable-cdn --cache-mode=CACHE_ALL_STATIC --default-ttl=3600 --max-ttl=86400
# Invalidate CDN cache after deployments
gcloud compute url-maps invalidate-cdn-cache my-url-map --global --path="/*" # Invalidate everything
# Invalidate specific paths
gcloud compute url-maps invalidate-cdn-cache my-url-map --global --path="/static/app.js" --path="/static/app.css"
# View CDN cache hit statistics
gcloud logging read 'resource.type="http_load_balancer" AND jsonPayload.statusDetails="response_from_cache"' --freshness=1h --format="table(timestamp,jsonPayload.httpRequest.requestUrl)"
Hybrid Connectivity: Cloud Interconnect
For connecting on-premises environments to GCP:
# Create a Dedicated Interconnect (for 10Gbps+ circuits from a colocation facility)
gcloud compute interconnects create my-interconnect --location=europe-west4 --interconnect-type=DEDICATED --link-type=LINK_TYPE_ETHERNET_10G_LR --requested-link-count=2 # 2 links for redundancy
--name=my-dedicated-interconnect
# Create VLAN attachments for each interconnect link
gcloud compute interconnects attachments dedicated create my-attachment-1 --region=europe-west4 --interconnect=my-interconnect --router=my-cloud-router --vlan=100 --bandwidth=BPS_10G
# For lower-bandwidth hybrid connectivity, use Cloud VPN
gcloud compute vpn-gateways create my-vpn-gateway --network=production-vpc --region=europe-west4
gcloud compute vpn-tunnels create my-vpn-tunnel --peer-ip=203.0.113.1 --shared-secret=your-shared-secret --region=europe-west4 --vpn-gateway=my-vpn-gateway --peer-gcp-gateway=peer-vpn-gateway --ike-version=2 --router=my-cloud-router
Network Connectivity Center
For complex hybrid topologies with multiple on-premises sites:
# Create a Network Connectivity Center hub
gcloud network-connectivity hubs create production-hub --description="Production network hub"
# Connect your VPN gateway as a spoke
gcloud network-connectivity spokes linked-vpn-tunnels create on-prem-spoke --hub=production-hub --region=europe-west4 --vpn-tunnels=my-vpn-tunnel-1,my-vpn-tunnel-2 --site-to-site-data-transfer
NCC simplifies routing between multiple connected environments: all VPN and Interconnect connections route through the hub, and NCC handles the BGP route propagation automatically.
For securing your network layer with WAF and DDoS protection, see our Cloud Armor guide. For Terraform modules that implement these network patterns, see our GCP Terraform best practices guide.