VPC Networks: Custom Mode and Subnets
Scenario
GCP default networks automatically create subnets in every single region across the globe. For greater control and security, you should use custom mode VPC networks where you explicitly define the regions and IP ranges you wish to route. You need to create a custom VPC with two regional subnets designed for backend services.
- Create a google_compute_network with auto_create_subnetworks = false to prevent default subnets from polluting your routing table.
- Create two google_compute_subnetwork resources in different regions (e.g., us-central1 and europe-west1).
- Enable Private Google Access (private_ip_google_access = true) on both subnets so VMs without public IPs can reach Google APIs (like Cloud Storage or Pub/Sub).
- Output the VPC ID and both subnet IDs.
Additional Context
GCP VPCs are global resources, whereas subnets are regional resources. This means a single VPC spans the world, and VMs in different regions can communicate on private internal IPs automatically — no need for complex VPC Peering or Transit Gateways like in AWS.
Private Google Access is a critical safety feature. Without it, a VM that only has a private IP cannot interact with GCP APIs natively and would fail to perform tasks like pushing metrics to Cloud Monitoring.
variables.tf
variable "project_id" { type = string }
variable "region_one" { type = string; default = "us-central1" }
variable "region_two" { type = string; default = "europe-west1" }main.tf
provider "google" {
project = var.project_id
}
# The Custom VPC
resource "google_compute_network" "custom_vpc" {
name = "global-custom-vpc"
# Crucial: turn off auto-creation of default subnets
auto_create_subnetworks = false
# Optional: affects dynamic BGP routing spread (regional vs global)
routing_mode = "GLOBAL"
}
# Subnet 1 in Region 1
resource "google_compute_subnetwork" "subnet_us" {
name = "subnet-us-central"
network = google_compute_network.custom_vpc.id
region = var.region_one
cidr_range = "10.10.0.0/24"
# Allows private VMs to reach Google APIs (Cloud Storage, etc.)
private_ip_google_access = true
}
# Subnet 2 in Region 2
resource "google_compute_subnetwork" "subnet_eu" {
name = "subnet-eu-west"
network = google_compute_network.custom_vpc.id
region = var.region_two
cidr_range = "10.20.0.0/24"
private_ip_google_access = true
}outputs.tf
output "vpc_id" {
value = google_compute_network.custom_vpc.id
}
output "subnet_us_id" {
value = google_compute_subnetwork.subnet_us.id
}
output "subnet_eu_id" {
value = google_compute_subnetwork.subnet_eu.id
}Workflow Commands
terraform init
terraform apply -var="project_id=my-gcp-project-123"
# List subnets within the new VPC
gcloud compute networks subnets list --network=global-custom-vpc
terraform destroy -var="project_id=my-gcp-project-123"Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs: subnet_eu_id = "projects/my-gcp-project-123/regions/europe-west1/subnetworks/subnet-eu-west" subnet_us_id = "projects/my-gcp-project-123/regions/us-central1/subnetworks/subnet-us-central" vpc_id = "projects/my-gcp-project-123/global/networks/global-custom-vpc"

