Skip to content

Shared VPC & Centralized Management — Enterprise Multi-Project Networking

Executive Summary

Shared VPC = một project (host) quản lý network cho nhiều projects (service projects).

Model:

  • ✅ Host project: Centralized network control
  • ✅ Service projects: Access host network via IAM
  • ✅ Cost attribution: Per-service-project billing
  • ✅ Security: Centralized firewall policy
  • ❌ Complexity: Requires careful IAM setup
  • ❌ Single point of failure: If host network fails, all services affected

Shared VPC vs VPC Peering

Comparison

yaml
Shared VPC:
  - Model: Hub-and-spoke (host + service projects)
  - Network owner: Host project (centralized)
  - Connectivity: All service projects share same VPC
  - Firewall policy: Host project controls
  - DNS: Private zones in host project
  - Cost: Allocated to service projects
  - Scaling: Unlimited service projects (in org)
  - Effort: More complex IAM setup

VPC Peering:
  - Model: Direct VPC-to-VPC connections
  - Network owner: Each VPC independent
  - Connectivity: Via peering relationships
  - Firewall policy: Per VPC (fragmented)
  - DNS: Each VPC manages own zones
  - Cost: Each VPC pays own egress
  - Scaling: O(N²) connections needed (mesh)
  - Effort: Simpler to set up

Shared VPC Architecture

Host Project Setup

Organization
└── Folder "Production"
    ├── Host Project "prod-network-host"
    │   └── VPC "shared-network" (10.0.0.0/16)
    │       ├── Subnet prod-app (10.0.1.0/24) us-central1
    │       ├── Subnet prod-db (10.0.2.0/24) us-central1
    │       └── Firewall rules

    ├── Service Project "prod-app-1"
    │   └── VMs attach to shared-network

    ├── Service Project "prod-app-2"
    │   └── VMs attach to shared-network

    └── Service Project "prod-db"
        └── VMs attach to shared-network

All VMs in all projects:
  - Share same VPC
  - Share same firewall rules
  - Communicate via VPC-local routing (low latency, free)

Enabling Shared VPC

bash
# Host project: Enable shared VPC
gcloud compute shared-vpc enable prod-network-host

# Attach service project to host project
gcloud compute shared-vpc associated-projects attach prod-app-1 \
  --host-project=prod-network-host

IAM Roles: Centralized Control

Host Project Roles

Network Admin (host project):
  - Role: compute.networkAdmin
  - Permissions:
    * Create/delete subnets
    * Create/manage firewall rules
    * Manage routes, VPN, Cloud Router

Shared VPC Admin (host project):
  - Role: compute.xpnAdmin
  - Permissions:
    * Attach/detach service projects
    * Manage Shared VPC settings

Service Project Admin (host project):
  - Role: compute.osAdminResource (?)
  - Cannot modify network
  - Can deploy VMs in existing subnets

Service Project Roles

Service Project Admin:
  - Can only deploy VMs/services
  - Cannot modify shared VPC
  - Cannot attach to different host project

Network User (service project):
  - Role: compute.networkUser
  - Permissions:
    * Deploy VMs in assigned subnets
    * Access firewall rules (read-only)
    * Launch instances in subnets

Subnet User (service project):
  - Role: compute.networkUser + resourcemanager.projectIamAdmin
  - Can delegate network access to other service projects

IAM Setup Example

bash
# Grant network admin to network team:
gcloud projects add-iam-policy-binding prod-network-host \
  --member=group:network-team@company.com \
  --role=roles/compute.networkAdmin

# Grant subnet user to prod-app-1 team:
gcloud projects add-iam-policy-binding prod-network-host \
  --member=group:prod-app-1-team@company.com \
  --role=roles/compute.networkUser \
  --condition='resource.matchTag("env", "prod-app-1")'

# Effect: Only prod-app-1 team can deploy VMs in prod-app-1 tagged subnets

Subnet Sharing: Granular Control

Sharing Subnets to Service Projects

bash
# By default, all subnets in host project are private

# Share subnet with service project:
gcloud compute networks subnets add-iam-policy-binding prod-app \
  --region=us-central1 \
  --member=serviceProject:prod-app-1 \
  --role=roles/compute.networkUser

# Effect:
#   prod-app-1 team can deploy VMs in this subnet
#   Cannot deploy in other subnets (prod-db, prod-cache, etc.)

Per-Subnet Isolation

Architecture:

Host project subnets:
  - prod-app (10.0.1.0/24) → shared with service-proj-app-1
  - prod-db (10.0.2.0/24) → shared with service-proj-db
  - prod-cache (10.0.3.0/24) → NOT shared (host-only)
  - monitoring (10.0.4.0/24) → shared with service-proj-monitoring

Service project: prod-app-1
  - Can deploy VMs in: prod-app subnet only
  - Cannot deploy in: prod-db, prod-cache, monitoring

Service project: prod-db
  - Can deploy VMs in: prod-db subnet only
  - Cannot deploy in: prod-app, prod-cache, monitoring

Result: Subnet-level isolation + shared VPC

Cost Attribution

Billing Breakdown

Host project costs:
  - Shared VPC management: $0 (no charge)
  - Subnet allocation: $0 (no charge)
  - Shared VPC instances: Billed to host project

Service project costs:
  - VMs deployed in shared VPC: Billed to service project
  - Network resources: GCP shares credit across both
  
Example:
  Host project: prod-network-host
    - VMs in subnets: $1000/month (billed to host)
  
  Service project: prod-app-1
    - VMs in subnets: $2000/month (billed to service-proj-app-1)
    
Total networking cost: ~$3000/month
  - Shared infrastructure: Not double-charged
  - Each project only pays for own VMs

Cost Allocation via Labels

bash
# Create VM in shared VPC with labels for cost allocation:

gcloud compute instances create app-server-1 \
  --network-interface=network-project=prod-network-host,network=shared-network,subnet=prod-app \
  --labels=cost-center=engineering,team=app-1 \
  --project=prod-app-1

# Billing export to BigQuery:
SELECT
  resource.labels.instance_id,
  resource.labels.zone,
  sum(cost) as total_cost
FROM `billing.gcp_billing_export`
WHERE resource.labels.project_id = 'prod-app-1'
  AND resource.labels.instance_id LIKE 'app-server-%'
GROUP BY instance_id, zone

Security: Centralized Firewall Policy

Firewall Rule Ownership

Host project:
  Firewall rule: allow tcp:443 from 0.0.0.0/0
  Effect: APPLIES to ALL service projects
  
Service project admin:
  Cannot create their own firewall rules
  Cannot override host firewall
  → Enforced security baseline

Hierarchical Enforcement

Organization Policy:
  Rule: DENY tcp:22 (SSH) globally

Shared VPC Host Project:
  Rule: ALLOW tcp:22 from corporate-network only

Service Project:
  Cannot override (no firewall rules allowed in service project)

Result:
  Organization policy enforced (DENY 22)
  SSH only from corporate network
  Service projects cannot bypass

Multi-Tenancy Patterns

Pattern 1: Team-based Isolation

Host project: prod-network-host
  Subnets:
    - team-a-app (10.0.1.0/24)
    - team-a-db (10.0.2.0/24)
    - team-b-app (10.0.3.0/24)
    - team-b-db (10.0.4.0/24)

Service projects:
  - prod-team-a (can deploy in team-a-* only)
  - prod-team-b (can deploy in team-b-* only)

Firewall rules:
  - Allow team-a-app ↔ team-a-db (tcp:5432)
  - Allow team-b-app ↔ team-b-db (tcp:3306)
  - DENY team-a ↔ team-b (complete isolation)

Result: Multi-tenant VPC with security boundaries

Pattern 2: Environment-based Isolation

Host project: unified-network-host
  Subnets:
    - prod-tier-1 (10.0.0.0/23)
    - prod-tier-2 (10.0.2.0/23)
    - staging-tier-1 (10.1.0.0/23)
    - staging-tier-2 (10.1.2.0/23)
    - dev-tier-1 (10.2.0.0/23)
    - dev-tier-2 (10.2.2.0/23)

Service projects:
  - prod (deploy in prod-* subnets)
  - staging (deploy in staging-* subnets)
  - dev (deploy in dev-* subnets)

Firewall rules:
  - Allow prod-tier-1 ↔ prod-tier-2
  - Allow staging-tier-1 ↔ staging-tier-2 (isolation from prod)
  - Allow dev-tier-1 ↔ dev-tier-2 (isolation from prod/staging)

Result: Shared infrastructure, isolated environments

Pattern 3: Cross-Project Database Access

Host project: prod-network-host
  Subnets:
    - app-tier (10.0.1.0/24)
    - db-tier (10.0.2.0/24)

Service projects:
  - app-1-proj (deploy app VMs in app-tier)
  - app-2-proj (deploy app VMs in app-tier)
  - db-proj (deploy database VMs in db-tier)

Firewall rules:
  - Allow app-tier → db-tier tcp:3306 (MySQL)
  
Result: Multiple app teams share database
        All communicate via shared VPC (low latency)
        Database team isolates per firewall rules

Troubleshooting Shared VPC

Symptom: VM Cannot Attach to Shared VPC

bash
Error: (gcloud.compute.instances.create)
  The network 'shared-network' in
  network-project 'prod-network-host' is not available...

Diagnosis:
1. Check if service project is attached:
   gcloud compute shared-vpc associated-projects list \
     --host-project=prod-network-host

2. If not listed, attach:
   gcloud compute shared-vpc associated-projects attach PROJECT_ID \
     --host-project=prod-network-host

3. Check IAM permissions:
   gcloud projects get-iam-policy prod-app-1 \
     --flatten="bindings[].members" \
     --format="table(bindings.members)"
   
   Must have: compute.networkUser role

4. Check subnet IAM:
   gcloud compute networks subnets get-iam-policy prod-app \
     --region=us-central1 \
     --project=prod-network-host

   Service project must be listed

Symptom: Cross-Project Communication Fails

bash
Diagnosis:

1. Check peering/connectivity:
   VM in proj-1 (10.0.1.5) → VM in proj-2 (10.1.1.10)
   
   Both in shared VPC? YES (verify above)

2. Check firewall rules:
   gcloud compute firewall-rules list \
     --filter="network:shared-network" \
     --project=prod-network-host

   Rule allows 10.0.1.0/24 10.1.1.0/24? Must exist

3. Test connectivity:
   gcloud compute ssh vm-1 --project=proj-1
   $ nc -zv 10.1.1.10 22
   
   Connection timeout? Firewall blocking
   Connection refused? Service not listening

Best Practices

Do:

  • Use Shared VPC for 3+ projects (cost-effective)
  • Separate host project from service projects (security)
  • Use IAM for granular access (subnet-level)
  • Document subnet assignments (team mapping)
  • Enable audit logging (track network changes)
  • Use network namespacing (team-specific subnet prefixes)

Don't:

  • Mix host and service project deployments (confusing)
  • Allow service projects to create VPCs (defeats purpose)
  • Ignore IAM setup (implicit permissions dangerous)
  • Over-share subnets (isolation defeated)
  • Use Shared VPC for simple single-project deployments

Migration: VPC Peering → Shared VPC

Scenario: Currently 3 VPCs with peering, migrating to Shared VPC

Steps:
1. Create host project
2. Create unified VPC with subnets covering all 3 old CIDRs
3. Attach service projects
4. Migrate VMs one-by-one (re-create with shared VPC)
5. Delete old VPCs after full migration
6. Delete peering connections

Timeline: ~2-4 weeks (careful planning needed)
Risk: Temporary dual-network during migration

Conclusion

Shared VPC provides centralized, scalable multi-project networking:

  • Host project: Single network control plane
  • Service projects: Limited to deployment (cannot change network)
  • Cost attribution: Per-project billing maintained
  • Security: Centralized firewall enforcement
  • Scaling: Unlimited service projects

Best for: Enterprise environments, 3+ projects, multi-team organizations.

Not needed: Single project or simple two-project scenarios (use peering).