Lab 2 — Cross-VPC Connectivity via VPC Peering¶
Code: 02-gcp-terraform/2-2VPCs/ · Resources Planned: 10 · Interactive View: Open Interactive Dashboard
1. Full Topology Overview¶
When workloads live in two separate VPCs (vpc-a with 10.10.0.0/24 and vpc-b with 10.20.0.0/24), they are completely isolated by default. VPC Network Peering connects both VPCs on Google's Andromeda SDN fabric so subnet routes are exchanged automatically with zero hourly tunnel charges and full line-rate bandwidth.
Click any diagram to open the full-resolution zoomable view, or launch the interactive HTML inspector.
2. Visual Breakdown by Layer¶
Part A — Zero-Trust IAP SSH & Cross-VPC Firewall Layer¶
VPC Peering exchanges routes, NOT firewall rules. Even after peering is ACTIVE, GCP's implied deny-all ingress rule on each VPC blocks packets arriving from the peer VPC until each VPC's firewall explicitly allows the other VPC's subnet CIDR:
vpc-a-allow(onvpc-a): Allows ingress from10.20.0.0/24(peersubnet-binvpc-b) and35.235.240.0/20(Google IAP TCP forwarding range for SSH).vpc-b-allow(onvpc-b): Mirrors the rule onvpc-b, allowing ingress from10.10.0.0/24(peersubnet-ainvpc-a) and35.235.240.0/20.
# Firewall: allow ICMP from the other VPC, SSH via IAP (35.235.240.0/20)
resource "google_compute_firewall" "a_allow" {
name = "vpc-a-allow"
network = google_compute_network.network-a.name
source_ranges = ["10.20.0.0/24", "35.235.240.0/20"]
allow { protocol = "icmp" }
allow {
protocol = "tcp"
ports = ["22"]
}
}
resource "google_compute_firewall" "b_allow" {
name = "vpc-b-allow"
network = google_compute_network.network-b.name
source_ranges = ["10.10.0.0/24", "35.235.240.0/20"]
allow { protocol = "icmp" }
allow {
protocol = "tcp"
ports = ["22"]
}
}
Part B — Bidirectional Peering Bridge (a-to-b & b-to-a) & Non-Overlapping Subnets¶
For VPC Peering to become ACTIVE, two independent google_compute_network_peering resources must be created — one initiated from vpc-a pointing to vpc-b, and one initiated from vpc-b pointing to vpc-a. If only one side is configured, the peering state remains INACTIVE and no routes are exchanged:
- Hard Prerequisite — Non-Overlapping CIDRs:
subnet-a(10.10.0.0/24) andsubnet-b(10.20.0.0/24) must not overlap with any subnet in the peer VPC (even subnets in other regions). - Non-Transitive Rule: VPC Peering is strictly non-transitive. If
VPC-A ↔ VPC-BandVPC-B ↔ VPC-Care peered,VPC-Acannot talk toVPC-CthroughVPC-B.
# Peering must be created from both sides to transition from INACTIVE -> ACTIVE
resource "google_compute_network_peering" "a_to_b" {
name = "a-to-b"
network = google_compute_network.network-a.self_link
peer_network = google_compute_network.network-b.self_link
}
resource "google_compute_network_peering" "b_to_a" {
name = "b-to-a"
network = google_compute_network.network-b.self_link
peer_network = google_compute_network.network-a.self_link
}
3. Theory to Resource Mapping & Plan Matrix (10 Resources)¶
| Networking Concept | Terraform Resource | Planned Instances (+10 total) |
|---|---|---|
| Isolated VPC Networks | google_compute_network |
network-a (vpc-a), network-b (vpc-b) |
| Non-Overlapping Subnets | google_compute_subnetwork |
subnet-a (10.10.0.0/24), subnet-b (10.20.0.0/24) |
| Symmetric VPC Peering | google_compute_network_peering |
a_to_b (vpc-a → vpc-b), b_to_a (vpc-b → vpc-a) |
| Ingress Firewalls | google_compute_firewall |
a_allow (vpc-a-allow), b_allow (vpc-b-allow) |
| Private Compute VMs | google_compute_instance |
a (vm-a), b (vm-b) |
4. Verification Commands¶
# 1. Verify both peerings show state: ACTIVE
gcloud compute networks peerings list
# 2. Inspect VPC A's route table to confirm 10.20.0.0/24 was imported via peering
gcloud compute routes list --filter="network:vpc-a"
# 3. Ping vm-b's internal IP from vm-a across the VPC peering link
gcloud compute ssh vm-a --zone us-central1-a --tunnel-through-iap \
--command "ping -c 4 $(terraform output -raw vm_b_ip)"
Cross-VPC Internal DNS Caveat
Notice that in Lab 1 (same VPC), ping vm-b worked by hostname because GCP's internal DNS (*.c.<project>.internal) is scoped to a single VPC. Across peered VPCs (Lab 2) or VPNs (Lab 3), you either ping by internal IP ($(terraform output -raw vm_b_ip)) or create a Cloud DNS Peering Zone.