Google Cloudadvanced

GCP VPC Network Segmentation: Subnets, Firewall Rules, and VPC Service Controls

Complete guide to implementing network segmentation in Google Cloud. Covers VPC design, subnet planning, firewall rules, Shared VPC architecture, and VPC Service Controls for data exfiltration prevention.

14 min readUpdated 2026-01-13

Network segmentation is a critical defense-in-depth strategy that limits an attacker's ability to move laterally after initial compromise. A flat network allows attackers to pivot from a compromised web server to databases containing sensitive data. Proper segmentation creates security boundaries that contain breaches.

This guide covers VPC architecture, firewall configuration, and advanced controls like VPC Service Controls. This expands on Tip 11 from our 30 Cloud Security Tips for 2026 guide on implementing network segmentation.

VPC Architecture Overview

A well-designed GCP network architecture includes:

  • Separate VPCs - Production vs. non-production environments
  • Tiered subnets - Web, application, and database tiers
  • Firewall rules - Explicit allow rules between tiers
  • VPC Service Controls - Data exfiltration prevention
  • Private Google Access - Access Google APIs without public IPs

Step 1: Create VPC Networks

Create separate VPCs for environment isolation:

Via Google Cloud Console

    - Navigate to [VPC Network](https://console.cloud.google.com/networking/networks) - Click **Create VPC Network** - Configure:
    • Name: prod-vpc

    • Subnet creation mode: Custom

    • MTU: 1460 (default) or 1500 for jumbo frames

    • Add subnets for each tier (see Step 2)

    • Click Create

Via gcloud CLI

# Create production VPC
gcloud compute networks create prod-vpc \
  --subnet-mode=custom \
  --bgp-routing-mode=regional \
  --project=PROJECT_ID

# Create staging VPC
gcloud compute networks create staging-vpc \
  --subnet-mode=custom \
  --bgp-routing-mode=regional \
  --project=PROJECT_ID

# Create development VPC
gcloud compute networks create dev-vpc \
  --subnet-mode=custom \
  --bgp-routing-mode=regional \
  --project=PROJECT_ID

Via Terraform

resource "google_compute_network" "prod_vpc" {
  name                    = "prod-vpc"
  auto_create_subnetworks = false
  routing_mode            = "REGIONAL"
  project                 = var.project_id
}

resource "google_compute_network" "staging_vpc" {
  name                    = "staging-vpc"
  auto_create_subnetworks = false
  routing_mode            = "REGIONAL"
  project                 = var.project_id
}

resource "google_compute_network" "dev_vpc" {
  name                    = "dev-vpc"
  auto_create_subnetworks = false
  routing_mode            = "REGIONAL"
  project                 = var.project_id
}

Step 2: Create Subnets for Network Tiers

Create subnets to segment by application tier:

Via gcloud CLI

# Web tier subnet (public-facing load balancers)
gcloud compute networks subnets create prod-web-subnet \
  --network=prod-vpc \
  --region=us-central1 \
  --range=10.0.1.0/24 \
  --enable-private-ip-google-access \
  --project=PROJECT_ID

# Application tier subnet
gcloud compute networks subnets create prod-app-subnet \
  --network=prod-vpc \
  --region=us-central1 \
  --range=10.0.2.0/24 \
  --enable-private-ip-google-access \
  --project=PROJECT_ID

# Database tier subnet
gcloud compute networks subnets create prod-db-subnet \
  --network=prod-vpc \
  --region=us-central1 \
  --range=10.0.3.0/24 \
  --enable-private-ip-google-access \
  --project=PROJECT_ID

# Management/bastion subnet
gcloud compute networks subnets create prod-mgmt-subnet \
  --network=prod-vpc \
  --region=us-central1 \
  --range=10.0.10.0/24 \
  --enable-private-ip-google-access \
  --project=PROJECT_ID

Via Terraform

resource "google_compute_subnetwork" "prod_web" {
  name          = "prod-web-subnet"
  ip_cidr_range = "10.0.1.0/24"
  region        = "us-central1"
  network       = google_compute_network.prod_vpc.id

  private_ip_google_access = true

  log_config {
    aggregation_interval = "INTERVAL_5_SEC"
    flow_sampling        = 0.5
    metadata             = "INCLUDE_ALL_METADATA"
  }
}

resource "google_compute_subnetwork" "prod_app" {
  name          = "prod-app-subnet"
  ip_cidr_range = "10.0.2.0/24"
  region        = "us-central1"
  network       = google_compute_network.prod_vpc.id

  private_ip_google_access = true

  log_config {
    aggregation_interval = "INTERVAL_5_SEC"
    flow_sampling        = 0.5
    metadata             = "INCLUDE_ALL_METADATA"
  }
}

resource "google_compute_subnetwork" "prod_db" {
  name          = "prod-db-subnet"
  ip_cidr_range = "10.0.3.0/24"
  region        = "us-central1"
  network       = google_compute_network.prod_vpc.id

  private_ip_google_access = true

  log_config {
    aggregation_interval = "INTERVAL_5_SEC"
    flow_sampling        = 0.5
    metadata             = "INCLUDE_ALL_METADATA"
  }
}

Step 3: Configure Firewall Rules

Create explicit allow rules between tiers:

Delete Default Rules

Remove overly permissive default rules:

# List default rules
gcloud compute firewall-rules list --filter="network=prod-vpc" --project=PROJECT_ID

# Delete default-allow-internal if it exists
gcloud compute firewall-rules delete default-allow-internal --project=PROJECT_ID

Create Tier-Based Rules

# Allow HTTPS from anywhere to web tier (through load balancer)
gcloud compute firewall-rules create prod-allow-lb-to-web \
  --network=prod-vpc \
  --direction=INGRESS \
  --priority=1000 \
  --action=ALLOW \
  --rules=tcp:80,tcp:443 \
  --source-ranges=130.211.0.0/22,35.191.0.0/16 \
  --target-tags=web-tier \
  --project=PROJECT_ID

# Allow web tier to app tier
gcloud compute firewall-rules create prod-allow-web-to-app \
  --network=prod-vpc \
  --direction=INGRESS \
  --priority=1000 \
  --action=ALLOW \
  --rules=tcp:8080 \
  --source-tags=web-tier \
  --target-tags=app-tier \
  --project=PROJECT_ID

# Allow app tier to database tier
gcloud compute firewall-rules create prod-allow-app-to-db \
  --network=prod-vpc \
  --direction=INGRESS \
  --priority=1000 \
  --action=ALLOW \
  --rules=tcp:5432,tcp:3306 \
  --source-tags=app-tier \
  --target-tags=db-tier \
  --project=PROJECT_ID

# Allow SSH from bastion only
gcloud compute firewall-rules create prod-allow-bastion-ssh \
  --network=prod-vpc \
  --direction=INGRESS \
  --priority=1000 \
  --action=ALLOW \
  --rules=tcp:22 \
  --source-tags=bastion \
  --target-tags=web-tier,app-tier,db-tier \
  --project=PROJECT_ID

# Deny all other internal traffic (explicit deny for logging)
gcloud compute firewall-rules create prod-deny-internal-all \
  --network=prod-vpc \
  --direction=INGRESS \
  --priority=65534 \
  --action=DENY \
  --rules=all \
  --source-ranges=10.0.0.0/8 \
  --enable-logging \
  --project=PROJECT_ID

Terraform Firewall Rules

resource "google_compute_firewall" "allow_lb_to_web" {
  name    = "prod-allow-lb-to-web"
  network = google_compute_network.prod_vpc.name

  allow {
    protocol = "tcp"
    ports    = ["80", "443"]
  }

  source_ranges = ["130.211.0.0/22", "35.191.0.0/16"]
  target_tags   = ["web-tier"]
  priority      = 1000
}

resource "google_compute_firewall" "allow_web_to_app" {
  name    = "prod-allow-web-to-app"
  network = google_compute_network.prod_vpc.name

  allow {
    protocol = "tcp"
    ports    = ["8080"]
  }

  source_tags = ["web-tier"]
  target_tags = ["app-tier"]
  priority    = 1000
}

resource "google_compute_firewall" "allow_app_to_db" {
  name    = "prod-allow-app-to-db"
  network = google_compute_network.prod_vpc.name

  allow {
    protocol = "tcp"
    ports    = ["5432", "3306"]
  }

  source_tags = ["app-tier"]
  target_tags = ["db-tier"]
  priority    = 1000
}

resource "google_compute_firewall" "deny_all_internal" {
  name    = "prod-deny-internal-all"
  network = google_compute_network.prod_vpc.name

  deny {
    protocol = "all"
  }

  source_ranges = ["10.0.0.0/8"]
  priority      = 65534

  log_config {
    metadata = "INCLUDE_ALL_METADATA"
  }
}

Step 4: Implement Shared VPC (Enterprise)

For large organizations, use Shared VPC to centralize network management:

Enable Shared VPC

# Enable host project
gcloud compute shared-vpc enable HOST_PROJECT_ID

# Attach service project
gcloud compute shared-vpc associated-projects add SERVICE_PROJECT_ID \
  --host-project=HOST_PROJECT_ID

Grant Subnet Access

# Grant service project access to specific subnet
gcloud compute networks subnets add-iam-policy-binding prod-app-subnet \
  --region=us-central1 \
  --member="serviceAccount:[email protected]" \
  --role="roles/compute.networkUser" \
  --project=HOST_PROJECT_ID

Terraform Shared VPC

resource "google_compute_shared_vpc_host_project" "host" {
  project = var.host_project_id
}

resource "google_compute_shared_vpc_service_project" "service" {
  host_project    = google_compute_shared_vpc_host_project.host.project
  service_project = var.service_project_id
}

resource "google_compute_subnetwork_iam_member" "network_user" {
  project    = var.host_project_id
  region     = "us-central1"
  subnetwork = google_compute_subnetwork.prod_app.name
  role       = "roles/compute.networkUser"
  member     = "serviceAccount:${var.service_project_number}@cloudservices.gserviceaccount.com"
}

Step 5: Configure VPC Service Controls

Create security perimeters to prevent data exfiltration:

Create Access Policy

# Create access policy (organization level)
gcloud access-context-manager policies create \
  --organization=ORGANIZATION_ID \
  --title="Production Security Policy"

Create Service Perimeter

# Create a perimeter protecting Cloud Storage and BigQuery
gcloud access-context-manager perimeters create prod-perimeter \
  --title="Production Perimeter" \
  --resources="projects/PROJECT_NUMBER" \
  --restricted-services="storage.googleapis.com,bigquery.googleapis.com" \
  --policy=POLICY_NUMBER

Create Access Level for Trusted Networks

# Create access level for corporate IP ranges
gcloud access-context-manager levels create trusted-network \
  --title="Trusted Network" \
  --basic-level-spec="ipSubnetworks=203.0.113.0/24,198.51.100.0/24" \
  --combine-function=AND \
  --policy=POLICY_NUMBER

# Update perimeter to allow access level
gcloud access-context-manager perimeters update prod-perimeter \
  --add-access-levels=trusted-network \
  --policy=POLICY_NUMBER

Terraform VPC Service Controls

resource "google_access_context_manager_access_policy" "policy" {
  parent = "organizations/${var.organization_id}"
  title  = "Production Security Policy"
}

resource "google_access_context_manager_access_level" "trusted_network" {
  parent = "accessPolicies/${google_access_context_manager_access_policy.policy.name}"
  name   = "accessPolicies/${google_access_context_manager_access_policy.policy.name}/accessLevels/trusted_network"
  title  = "Trusted Network"

  basic {
    conditions {
      ip_subnetworks = ["203.0.113.0/24", "198.51.100.0/24"]
    }
  }
}

resource "google_access_context_manager_service_perimeter" "prod_perimeter" {
  parent = "accessPolicies/${google_access_context_manager_access_policy.policy.name}"
  name   = "accessPolicies/${google_access_context_manager_access_policy.policy.name}/servicePerimeters/prod_perimeter"
  title  = "Production Perimeter"

  status {
    resources = ["projects/${var.project_number}"]

    restricted_services = [
      "storage.googleapis.com",
      "bigquery.googleapis.com"
    ]

    access_levels = [
      google_access_context_manager_access_level.trusted_network.name
    ]
  }
}

Step 6: Enable VPC Flow Logs

Monitor network traffic for security analysis:

# Enable flow logs on existing subnet
gcloud compute networks subnets update prod-app-subnet \
  --region=us-central1 \
  --enable-flow-logs \
  --logging-aggregation-interval=interval-5-sec \
  --logging-flow-sampling=0.5 \
  --logging-metadata=include-all \
  --project=PROJECT_ID

Best Practices Summary

  • Separate VPCs per environment - Production, staging, development isolation
  • Use subnet tiers - Web, app, database with explicit firewall rules
  • Default deny - Only allow explicitly required traffic
  • Use network tags or service accounts - More flexible than IP-based rules
  • Enable VPC Flow Logs - For traffic analysis and forensics
  • Implement VPC Service Controls - Prevent data exfiltration
  • Use Private Google Access - Access APIs without public IPs
  • Deploy Cloud NAT - Outbound internet without public IPs

Need help designing a secure network architecture for your Google Cloud environment? Contact InventiveHQ for expert guidance on VPC design and security controls.

Frequently Asked Questions

Find answers to common questions

A standard VPC Network exists within a single project and resources in that VPC are managed by that project. Shared VPC allows a VPC to be shared across multiple projects in an organization - the VPC is owned by a host project while service projects can create resources that use subnets from the host project. Shared VPC enables centralized network management while maintaining project-level resource isolation, and is recommended for enterprise deployments.

Expert GCP Management

From architecture design to managed operations, we handle your Google Cloud infrastructure.