✓Google Cloud Platform account with Organization, gcloud CLI (>= 400.0.0), Terraform (>= 1.3), basic understanding of VPC networking, IAM, and GKE
โฆ Definition~90s read
What is Shared VPC?
GCP Shared VPC lets you centrally manage a single Virtual Private Cloud network across multiple Google Cloud projects, enabling consistent policy enforcement, simplified routing, and reduced administrative overhead. It matters because it decouples network ownership from application ownership, allowing platform teams to control network security while giving service teams autonomy over their compute resources.
โ
GCP Shared VPC: Centralized Network Administration for Multi-Project is like having a specialized tool that handles shared vpc so you don't have to build and manage it yourself โ it just works out of the box with Google Cloud's infrastructure.
Use it when you need to scale multi-project architectures with strict compliance, centralized egress, or shared services like Cloud NAT and Private Google Access.
Plain-English First
GCP Shared VPC: Centralized Network Administration for Multi-Project is like having a specialized tool that handles shared vpc so you don't have to build and manage it yourself โ it just works out of the box with Google Cloud's infrastructure.
You deployed a new microservice in a separate project, and suddenly your production database is unreachable. The network team blames the app team, the app team blames IAM, and three hours later you discover someone deleted a VPC peering connection. This is the reality of managing networks without Shared VPC. GCP Shared VPC flips the model: one network, many projects, central control. It eliminates the complexity of VPC peering meshes, reduces attack surface by enforcing consistent firewall rules, and gives you a single pane of glass for audit logs. If you're running more than three projects with any inter-project communication, you're wasting time and risking outages without it. This article walks you through the architecture, implementation, and operational pitfalls of Shared VPC โ from a production engineer who's cleaned up the mess when it's done wrong.
The Shared VPC Architecture: Host vs. Service Projects
Shared VPC splits responsibility into two project types: the host project owns the VPC network, subnets, firewall rules, and routes. Service projects attach to the host and consume its subnets for their resources (GKE, Compute Engine, Cloud SQL, etc.). This separation is critical: the host project is managed by a central network team, while service project owners deploy workloads without touching network configuration. The host project can have multiple VPCs, but each service project attaches to exactly one host project. Resources in service projects get IPs from the host project's subnets, and all traffic flows through the host project's firewall rules. This means you can enforce egress via Cloud NAT in the host project, block SSH from the internet globally, and audit all traffic with VPC Flow Logs from a single project. The key constraint: service projects cannot create their own subnets or modify host project firewall rules. This is a feature, not a bug โ it prevents the sprawl that plagues multi-project setups.
enable-shared-vpc.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
# EnableSharedVPCfor host project
HOST_PROJECT_ID="network-host-prod"
SERVICE_PROJECT_ID="app-service-prod"
gcloud compute shared-vpc enable "$HOST_PROJECT_ID"
# Attach service project to host
gcloud compute shared-vpc associated-projects add "$SERVICE_PROJECT_ID" \
--host-project "$HOST_PROJECT_ID"
# Grant service project network user role to a service account
gcloud projects add-iam-policy-binding "$SERVICE_PROJECT_ID" \
--member="serviceAccount:app-sa@$SERVICE_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/compute.networkUser" \
--condition="expression=resource.name.startsWith('projects/$HOST_PROJECT_ID/regions/us-central1/subnetworks/app-subnet'),title=restrict_to_app_subnet"
Output
Shared VPC enabled for [network-host-prod].
Associated project [app-service-prod] added.
Updated IAM policy for project [app-service-prod].
โ IAM Condition Gotcha
Without IAM conditions, granting compute.networkUser gives access to ALL subnets in the host project. Always scope to specific subnets using resource.name conditions to prevent accidental cross-environment access.
๐ Production Insight
In production, we saw a team attach a staging service project to a production host project because the host project name was ambiguous. Use naming conventions like 'prod-network-host' and 'staging-network-host' to avoid cross-environment leaks.
๐ฏ Key Takeaway
Shared VPC separates network ownership from workload ownership via host and service projects.
thecodeforge.io
Gcp Shared Vpc
Subnet Design: Carving Out Space for Scale
Subnet planning in Shared VPC is a one-time decision that haunts you forever if done wrong. Each subnet belongs to the host project and is assigned to a region. Service projects can use any subnet they have IAM access to. The golden rule: use non-overlapping CIDR ranges per environment and per region. For production, reserve /16 per region (e.g., 10.0.0.0/16 for us-central1, 10.1.0.0/16 for us-east1). For staging, use a different prefix like 10.64.0.0/16. Never use the same CIDR across environments โ it breaks peering and migration. Secondary ranges are essential for GKE pods and services: allocate /16 for pods and /20 for services per cluster. Use a consistent naming scheme: 'subnet-prod-us-central1-app', 'subnet-prod-us-central1-gke-pods'. Avoid creating subnets larger than /16; you'll waste IPs and hit routing table limits. Also, plan for future regions: leave gaps in your IP space (e.g., skip 10.2.0.0/16 for future us-west1).
google_compute_subnetwork.subnets["prod-us-central1-app"]: Creation complete after 12s
google_compute_subnetwork.subnets["prod-us-east1-app"]: Creation complete after 11s
๐กSecondary Ranges Are Not Optional
GKE requires secondary ranges for pods and services. If you skip them, you'll be forced to use VPC-native clusters with auto-allocated ranges, which can conflict with existing routes. Always define them upfront.
๐ Production Insight
We once allocated a /24 for GKE pods in a /16 subnet. After 50 clusters, we ran out of pod IPs. Use at least /20 per cluster for pods, and monitor utilization with VPC IP space alerts.
๐ฏ Key Takeaway
Plan subnet CIDRs with non-overlapping ranges per environment and region, and always include secondary ranges for GKE.
IAM and Access Control: The Network User Role
The compute.networkUser role is the linchpin of Shared VPC security. It grants a service project's identities (users, service accounts, groups) permission to use subnets in the host project. Without it, resources in the service project cannot create network interfaces. The role must be granted at the host project level, but you should scope it with IAM conditions to specific subnets. For example, a staging service project should only access staging subnets. Use groups for role assignment: create a group like 'gcp-network-users-prod' and add service accounts to it. This avoids managing individual bindings. Also, grant compute.networkUser to the GKE service agent (service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com) so GKE clusters can create nodes in the host project's subnets. Never grant compute.networkAdmin to service project users โ that allows them to modify firewall rules and routes, defeating the purpose of centralization.
iam-network-user.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
HOST_PROJECT="network-host-prod"
SERVICE_PROJECT="app-service-prod"SUBNET="projects/$HOST_PROJECT/regions/us-central1/subnetworks/subnet-prod-us-central1-app"
# Grant networkUser to a group
gcloud projects add-iam-policy-binding "$HOST_PROJECT" \
--member="group:gcp-network-users-prod@example.com" \
--role="roles/compute.networkUser" \
--condition="expression=resource.name.startsWith('$SUBNET'),title=restrict_to_app_subnet"
# Grant networkUser to GKE service agent
GKE_SA="service-$(gcloud projects describe $SERVICE_PROJECT --format='value(projectNumber)')@container-engine-robot.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding "$HOST_PROJECT" \
--member="serviceAccount:$GKE_SA" \
--role="roles/compute.networkUser" \
--condition="expression=resource.name.startsWith('$SUBNET'),title=gke_subnet_access"
Output
Updated IAM policy for project [network-host-prod].
Updated IAM policy for project [network-host-prod].
โ GKE Service Agent Needs Explicit Access
If you forget to grant compute.networkUser to the GKE service agent, cluster creation will fail with 'permission denied' on the subnet. Always add it before creating clusters.
๐ Production Insight
We had a production outage because a new team member granted compute.networkAdmin to a service project. They accidentally deleted a firewall rule, exposing a Cloud SQL instance to the internet. Audit IAM bindings weekly.
๐ฏ Key Takeaway
Use IAM conditions to scope compute.networkUser to specific subnets, and always grant it to GKE service agents.
thecodeforge.io
Gcp Shared Vpc
Firewall Rules: Centralized Enforcement with Service Project Exceptions
Firewall rules in Shared VPC are defined in the host project and apply to all resources in attached service projects. This is powerful: you can block all inbound SSH from the internet with a single rule. However, service projects sometimes need their own rules (e.g., allow health checks from a specific range). You have two options: create global rules in the host project, or use service project firewall rules (which are allowed but discouraged). The best practice is to centralize all ingress rules in the host project and use network tags for fine-grained control. For example, tag all GKE nodes with 'gke-node' and create a rule allowing port 10250 from monitoring ranges. Avoid service project firewall rules because they create a fragmented policy that's hard to audit. Use hierarchical firewall policies for organization-level rules that apply across all host projects. Also, enable VPC Flow Logs on subnets to capture denied traffic โ it's invaluable for debugging.
google_compute_firewall.fw-allow-health-checks: Creation complete after 8s
google_compute_firewall.fw-deny-all-ssh: Creation complete after 7s
google_compute_firewall.fw-allow-ssh-from-bastion: Creation complete after 7s
๐ฅFirewall Priority Matters
GCP firewall rules have a priority from 0 (highest) to 65535 (lowest). Default rules have priority 65535. Always set explicit priorities for deny rules to ensure they override allows. Use priority 1000 for denies and 900 for specific allows.
๐ Production Insight
A team created a service project firewall rule allowing all traffic from 0.0.0.0/0 to port 3306, thinking it only applied to their project. It didn't โ it applied to all resources in the host project's VPC. We caught it with a VPC Flow Log alert on denied traffic. Always audit service project firewall rules.
๐ฏ Key Takeaway
Centralize firewall rules in the host project and use network tags for granularity; avoid service project firewall rules.
Private Google Access and Cloud NAT: Centralized Egress
Shared VPC enables centralized egress through Cloud NAT and Private Google Access. Configure Cloud NAT in the host project on each subnet that needs outbound internet access. Service project resources automatically use this NAT โ no per-project configuration needed. This is critical for compliance: all outbound traffic goes through a single set of IPs, simplifying allowlisting with third parties. Private Google Access allows VMs without external IPs to reach Google APIs (e.g., Cloud Storage, BigQuery) over Google's internal network. Enable it per subnet in the host project. The combination means service project VMs can have zero public IPs, reducing attack surface. However, beware of NAT gateway limits: each Cloud NAT gateway supports up to 64,000 concurrent connections per VM. For high-throughput workloads, use multiple NAT IPs or consider a third-party NVA. Also, monitor NAT gateway utilization with Cloud Monitoring to avoid connection drops.
cloud-nat.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
resource "google_compute_router""router" {
name = "router-prod-us-central1"
network = google_compute_network.vpc.name
region = "us-central1"
}
resource "google_compute_router_nat""nat" {
name = "nat-prod-us-central1"
router = google_compute_router.router.name
region = "us-central1"
nat_ip_allocate_option = "AUTO_ONLY"
source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS"
subnetwork {
name = google_compute_subnetwork.subnets["prod-us-central1-app"].id
source_ip_ranges_to_nat = ["ALL_IP_RANGES"]
}
# Enable logging for audit
log_config {
enable = true
filter = "ERRORS_ONLY"
}
}
# EnablePrivateGoogleAccess on subnet
resource "google_compute_subnetwork""subnet_with_pga" {
name = "subnet-prod-us-central1-app"
network = google_compute_network.vpc.id
region = "us-central1"
ip_cidr_range = "10.0.0.0/20"
private_ip_google_access = true
}
Output
google_compute_router.router: Creation complete after 10s
google_compute_router_nat.nat: Creation complete after 15s
google_compute_subnetwork.subnet_with_pga: Creation complete after 12s
๐กNAT Logging Is Cheap Insurance
Enable NAT logging with ERRORS_ONLY filter to capture dropped connections. It's low volume and helps debug egress failures without drowning in data.
๐ Production Insight
We had a batch job that opened 100,000 connections to an external API. Cloud NAT's 64,000 connection limit per VM caused random failures. We switched to static NAT IPs and spread the workload across multiple VMs. Monitor connection counts with Cloud Monitoring.
๐ฏ Key Takeaway
Centralize egress with Cloud NAT and Private Google Access in the host project to eliminate public IPs on VMs.
VPC Peering and Hybrid Connectivity: Extending the Shared VPC
Shared VPC networks can peer with other VPCs (including on-prem via Cloud VPN or Dedicated Interconnect). This allows you to extend the centralized network model to hybrid environments. For example, peer the host project's VPC with a on-prem network via Cloud VPN, and all service projects automatically get connectivity to on-prem resources. However, peering is not transitive: if VPC A is peered with VPC B, and VPC B is peered with VPC C, VPC A does not automatically reach VPC C. You must set up direct peering between A and C. Also, beware of overlapping CIDRs โ they break peering. Use non-overlapping ranges from the start. For hybrid connectivity, use a dedicated project for VPN/Interconnect and peer it with the host project. This keeps the network team in control of the VPN tunnel while service projects remain unaware. Use Cloud Router with dynamic routing (BGP) to propagate routes automatically.
google_compute_network_peering.peer-with-onprem: Creation complete after 20s
google_compute_router.hybrid-router: Creation complete after 10s
google_compute_vpn_tunnel.tunnel: Creation complete after 30s
โ Peering Route Limits
Each VPC can have up to 100 dynamic routes from Cloud Router. If you have many on-prem subnets, aggregate them into larger CIDRs to stay under the limit.
๐ Production Insight
We peered a Shared VPC with an on-prem network that had overlapping CIDR (10.0.0.0/8). Traffic to on-prem was blackholed. We had to re-IP the on-prem network โ a six-month project. Always verify no overlap before peering.
๐ฏ Key Takeaway
Peer the host VPC with on-prem networks for hybrid connectivity; peering is not transitive, so plan accordingly.
GKE in Shared VPC: Cluster Configuration and Node Pools
Deploying GKE clusters in a Shared VPC requires careful configuration. The cluster's VPC-native mode must use the host project's subnets. Specify the subnet for nodes, and secondary ranges for pods and services. The GKE service agent needs compute.networkUser on the subnet. Node pools can use different subnets, but all must be in the same region as the cluster. Use separate node pools for system and user workloads, each with its own subnet if needed. Enable Dataplane V2 for better network policy enforcement. Also, configure master authorized networks to restrict access to the control plane. A common pitfall: forgetting to grant the GKE service agent access to the subnet's secondary ranges. The error message is cryptic: 'failed to create cluster: googleapi: Error 400: Invalid value for field 'resource.clusterIpv4Cidr' โ but the real issue is IAM. Always test cluster creation with a dry run.
Creating cluster app-cluster in us-central1... Cluster is being health-checked... done.
๐ฅDry Run Before Creating
Use --dry-run flag to validate cluster creation without actually creating it. This catches IAM and subnet issues early.
๐ Production Insight
We had a cluster that failed to create because the secondary range name was misspelled. The error said 'subnet not found' but the real issue was a typo. Use Terraform to avoid manual errors.
๐ฏ Key Takeaway
GKE in Shared VPC requires explicit subnet and secondary range references, plus IAM for the GKE service agent.
Monitoring and Auditing: VPC Flow Logs and Network Intelligence Center
Visibility is non-negotiable in Shared VPC. Enable VPC Flow Logs on all subnets in the host project to capture traffic metadata. Sample rate of 1 in 10 is sufficient for most environments; increase to 1 in 2 for critical subnets. Export logs to BigQuery for analysis โ you can detect anomalous traffic, identify unused IPs, and troubleshoot connectivity. Use Network Intelligence Center (NIC) for topology visualization and connectivity tests. NIC can simulate traffic between any two endpoints and show the path, firewall rules applied, and any drops. This is invaluable for debugging 'why can't VM A talk to VM B' in a multi-project setup. Also, set up alerts for high NAT connection counts, dropped packets, and firewall rule changes. Use Cloud Monitoring dashboards to track subnet utilization and alert when IP space is below 20%.
google_compute_subnetwork.subnet_with_logs: Creation complete after 12s
google_logging_project_sink.flow_logs_bq: Creation complete after 5s
๐กFlow Logs Cost Money โ Sample Wisely
At 0.1 sampling, a busy subnet can generate hundreds of GB per day. Set a budget alert on BigQuery costs. Use INTERVAL_5_SEC for high-fidelity or INTERVAL_1_MIN for cost savings.
๐ Production Insight
We discovered a crypto miner in a service project by analyzing VPC Flow Logs for traffic to known mining pools. The logs showed outbound connections to a suspicious IP. We shut it down within an hour.
๐ฏ Key Takeaway
Enable VPC Flow Logs and use Network Intelligence Center for visibility; export logs to BigQuery for analysis.
Organizational Policy and Hierarchy: Enforcing Shared VPC at Scale
At the organization level, you can enforce Shared VPC usage via organizational policies. Use the compute.restrictSharedVpcHostProject constraint to limit which projects can be host projects. This prevents rogue teams from creating their own Shared VPCs. Also, use compute.restrictSharedVpcSubnetworks to restrict which subnets service projects can use. Combine with IAM conditions for defense in depth. For large organizations, use folder-level host projects: each folder (e.g., 'Production', 'Staging') has its own host project. This isolates environments. Use Terraform to manage the hierarchy: create host projects per folder, attach service projects, and apply firewall rules. Automate with CI/CD to prevent drift. Also, set up a centralized network CI/CD pipeline that deploys firewall rules and subnets from a single repository. This ensures all changes are reviewed and audited.
google_organization_policy.restrict_host_projects: Creation complete after 15s
google_folder_organization_policy.restrict_subnets: Creation complete after 12s
โ Org Policies Are Slow to Propagate
Changes to organizational policies can take up to 24 hours to propagate. Plan ahead and test in a non-production folder first.
๐ Production Insight
We had a team create a host project in the 'Development' folder that used the same CIDR as production. Org policies prevented it, but only after we added the constraint. Implement policies before onboarding teams.
๐ฏ Key Takeaway
Use organizational policies to restrict which projects can be host projects and which subnets service projects can use.
Migration from VPC Peering to Shared VPC
Migrating from a VPC peering mesh to Shared VPC is painful but necessary for scale. The key challenge: you cannot change the network of existing resources. You must recreate them in the Shared VPC. Strategy: create the Shared VPC host project and subnets, then gradually migrate workloads. For GCE instances, use instance templates with the new subnet and rolling update. For GKE, create a new cluster in the Shared VPC and migrate workloads using a blue-green deployment. For Cloud SQL, you must restore a backup into the new VPC. Use a migration project as a staging ground: attach it to the host project, deploy new resources, and cut over traffic. During migration, maintain peering between old and new VPCs for connectivity. Once all workloads are migrated, delete the old VPCs and peering connections. This process can take weeks โ plan for downtime windows.
migrate-instance.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# Createnew instance in SharedVPC
OLD_INSTANCE="web-server-old"
NEW_INSTANCE="web-server-new"ZONE="us-central1-a"SUBNET="projects/network-host-prod/regions/us-central1/subnetworks/subnet-prod-us-central1-app"
gcloud compute instances create "$NEW_INSTANCE" \
--zone "$ZONE" \
--subnet "$SUBNET" \
--source-instance-template "web-server-template" \
--no-address
# After verifying new instance, delete old one
gcloud compute instances delete "$OLD_INSTANCE" --zone "$ZONE" --quiet
Output
Created instance [web-server-new] in zone [us-central1-a].
Deleted instance [web-server-old].
๐ฅUse Managed Instance Groups for Zero-Downtime Migration
For stateless workloads, use MIGs with rolling update to switch to new instances in the Shared VPC. Set the update type to proactive and maxSurge to 1.
๐ Production Insight
We migrated a 200-node GKE cluster by creating a new cluster in Shared VPC and using a service mesh to shift traffic gradually. The migration took two weeks but had zero downtime. Plan for double resource costs during migration.
๐ฏ Key Takeaway
Migration to Shared VPC requires recreating resources; use blue-green deployments and maintain peering during transition.
Common Pitfalls and How to Avoid Them
Even experienced teams hit these Shared VPC landmines. First: overlapping CIDRs. Always use a central IPAM tool to track allocations. Second: forgetting IAM conditions. Without them, a staging service account can accidentally use production subnets. Third: ignoring GKE service agent IAM. Cluster creation fails silently. Fourth: not planning for secondary ranges. You can't add them later without recreating the subnet. Fifth: assuming peering is transitive. It's not โ you need explicit peering for each pair. Sixth: not enabling VPC Flow Logs from day one. You'll have no baseline for anomaly detection. Seventh: allowing service project firewall rules. They create a security blind spot. Eighth: not using organizational policies. Without them, teams can create their own host projects, defeating centralization. Mitigate each with automation: use Terraform to enforce standards, run policy-as-code checks in CI/CD, and conduct regular audits.
check-overlap.shHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
# CheckforCIDR overlap between two projects
PROJECT_A="prod-network-host"
PROJECT_B="staging-network-host"
gcloud compute networks subnets list --project $PROJECT_A --format='value(ipCidrRange)' | sort > /tmp/subnets_a.txt
gcloud compute networks subnets list --project $PROJECT_B --format='value(ipCidrRange)' | sort > /tmp/subnets_b.txt
# Use grep to find overlapping ranges (simplified)
while read cidr; doif grep -q "$cidr" /tmp/subnets_b.txt; then
echo "Overlap found: $cidr"
fi
done < /tmp/subnets_a.txt
Output
Overlap found: 10.0.0.0/16
โ IPAM Is Not Optional
Use a spreadsheet or a tool like phpIPAM to track CIDR allocations. Without it, you will have overlaps. We learned this the hard way after a three-hour outage.
๐ Production Insight
A team created a subnet with the same CIDR as an existing on-prem network. Traffic to on-prem was silently dropped. We now run a CIDR overlap check in every Terraform plan.
๐ฏ Key Takeaway
Avoid common pitfalls by using IAM conditions, planning secondary ranges, and enforcing organizational policies.
Automation with Terraform and CI/CD
Manual Shared VPC management doesn't scale. Use Terraform to define the entire network as code. Store state in a remote backend with locking. Organize modules: one for host project, one for subnets, one for firewall rules, one for IAM. Use workspaces or folders for environments. CI/CD pipeline: run terraform plan on every PR, require approval for production changes, and apply automatically after merge. Use Terratest or OPA for policy-as-code: enforce that all subnets have flow logs enabled, no public IPs on VMs, and firewall rules are tagged. Also, use Google Cloud Build or Terraform Cloud for execution. This ensures consistency and auditability. A common mistake: using terraform import for existing resources without updating state. Always run terraform plan after import to detect drift.
google_cloudbuild_trigger.network-cicd: Creation complete after 8s
๐กUse Terraform Import for Existing Networks
If you have an existing Shared VPC, use terraform import to bring it under management. But be careful: import doesn't generate code โ you must write the configuration manually.
๐ Production Insight
We had a production outage because someone manually added a firewall rule via the console that conflicted with Terraform. Now we use a CI/CD pipeline that reverts any manual changes within 5 minutes.
๐ฏ Key Takeaway
Automate Shared VPC with Terraform and CI/CD to enforce consistency and auditability.
Subnet-Level IAM vs Project-Level: Least Privilege for Shared VPC
When granting compute.networkUser to service project teams, you have two approaches: project-level or subnet-level IAM. Project-level grants access to ALL subnets in the host project, including future ones. This is simpler but violates least privilegeโa staging team could accidentally use production subnets. Subnet-level IAM binds the role directly on individual subnets, scoping access precisely. To do this, use gcloud compute networks subnets add-iam-policy-binding instead of gcloud projects add-iam-policy-binding. The trade-off: subnet-level requires more management but provides blast radius containment. For organizations with more than 5 service projects, manage subnet IAM with Terraform to avoid drift. A common pattern: create Google Groups per team (e.g., gcp-network-web-team@), grant subnet-level networkUser to the group, and manage group membership in your identity provider. Never use set-iam-policy on subnetsโit replaces the entire policy and can accidentally revoke other teams' access. Always use add-iam-policy-binding.
subnet-iam.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
resource "google_compute_subnetwork_iam_binding""web_team" {
project = "network-host-prod"
region = "us-central1"
subnetwork = "subnet-prod-web"
role = "roles/compute.networkUser"
members = [
"group:gcp-network-web-team@example.com",
"serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com",
]
}
resource "google_compute_subnetwork_iam_binding""data_team" {
project = "network-host-prod"
region = "us-east1"
subnetwork = "subnet-prod-data"
role = "roles/compute.networkUser"
members = [
"group:gcp-network-data-team@example.com",
]
}
Output
Terraform will create 2 IAM bindings.
Apply complete!
๐กGroups Over Individuals
Bind IAM roles to Google Groups, not individual users. When a team member joins or leaves, update the group, not the IAM policy. This prevents policy bloat and accidental access.
๐ Production Insight
We found a service project with project-level networkUser that was using a production subnet in us-east1 by accidentโtheir staging apps ran on production infrastructure. Switching to subnet-level IAM and groups eliminated this class of misconfiguration overnight.
๐ฏ Key Takeaway
Subnet-level IAM grants least-privilege access to specific subnets; manage with Terraform and Google Groups.
Shared VPC vs. Peered VPCTrade-offs between centralized and distributed network managementShared VPCVPC PeeringNetwork AdministrationCentralized in host projectDistributed across projectsSubnet ManagementSingle pool, carved into subnetsSeparate subnets per projectIAM ControlNetwork User role for granular accessProject-level IAM per VPCFirewall RulesCentralized, applied to all subnetsPer-VPC rules, no global viewScalabilityEasier to add new service projectsRequires new peering for each projectHybrid ConnectivitySingle VPN/Direct Connect for allSeparate connections per VPCTHECODEFORGE.IO
thecodeforge.io
Gcp Shared Vpc
Service Account-Based Firewall Rules vs Network Tags
GCP firewall rules traditionally use network tags (targetTags) to determine which VMs a rule applies to. However, network tags can be set by anyone with compute.instanceAdmin role, creating a security gap: a developer can tag a VM as 'http-server' and circumvent intended restrictions. Service account-based firewall rules are more secure because they use IAM identity, which is harder to spoof. Instead of target_tags = ["web-server"], use target_service_accounts = ["web-sa@project.iam.gserviceaccount.com"]. Any VM running as that service account automatically gets the firewall rule. This provides better audit trails and prevents tag-based privilege escalation. For production, prefer service account-based rules for sensitive applications (databases, internal APIs) and use network tags only for coarse-grained controls like health check allowlists. Migrate existing tag-based rules gradually: audit which service accounts should have access, create the rules, then remove tag-based rules.
A VM's service account cannot be changed after creation. Plan your service account strategy before deploying workloads. Use one service account per tier (web, app, db) for consistent firewall enforcement.
๐ Production Insight
A developer tagged their VM as 'db-tier' to debug a connectivity issue, accidentally exposing it to the app tier's firewall allow rule. With service account-based rules, this wouldn't have been possible because the VM's service account was immutable. We now enforce service account rules for all production firewall policies.
๐ฏ Key Takeaway
Prefer service account-based firewall rules over network tags for IAM-backed, auditable network security.
Service Account-Based Firewall Rules vs Network Tags
Key takeaways
1
Centralized Network Control
Shared VPC decouples network ownership from workload ownership, allowing a central team to manage subnets, firewalls, and egress while service teams deploy freely.
2
IAM Scoping Is Critical
Always use IAM conditions to restrict compute.networkUser to specific subnets, preventing cross-environment access and reducing blast radius.
3
Plan IP Space Generously
Allocate non-overlapping CIDR ranges per environment and region, include secondary ranges for GKE, and use an IPAM tool to avoid conflicts.
4
Automate Everything
Use Terraform and CI/CD to manage Shared VPC resources, enforce policies with OPA, and audit changes to prevent drift and manual errors.
Common mistakes to avoid
3 patterns
×
Ignoring gcp shared vpc best practices
Symptom
Production incidents and unexpected behavior
Fix
Follow GCP documentation and implement proper monitoring and testing
×
Over-provisioning without rightsizing analysis
Symptom
Wasted cloud spend and poor resource utilization
Fix
Use committed use discounts and rightsize based on actual usage metrics
×
Skipping IAM least-privilege principles
Symptom
Security vulnerabilities and compliance violations
Fix
Implement custom roles with minimum required permissions and use conditions
INTERVIEW PREP · PRACTICE MODE
Interview Questions on This Topic
Q01JUNIOR
What is GCP Shared VPC: Centralized Network Administration for Multi-Pro...
Q02SENIOR
How do you configure GCP Shared VPC: Centralized Network Administration ...
Q03SENIOR
What are the cost optimization strategies for GCP Shared VPC: Centralize...
Q01 of 03JUNIOR
What is GCP Shared VPC: Centralized Network Administration for Multi-Project and when would you use it in production?
ANSWER
GCP Shared VPC: Centralized Network Administration for Multi-Project is a Google Cloud service for managing infrastructure efficiently. It's ideal for organizations needing scalable, reliable cloud solutions. Use it when you need automated management and consistent performance across your GCP projects.
Q02 of 03SENIOR
How do you configure GCP Shared VPC: Centralized Network Administration for Multi-Project for high availability across regions?
ANSWER
Design for multi-region redundancy by distributing resources across at least two regions. Use Cloud DNS with geo-routing, configure health checks, implement automated failover, and regularly test disaster recovery procedures. Monitor with Cloud Monitoring and set up appropriate alerting policies.
Q03 of 03SENIOR
What are the cost optimization strategies for GCP Shared VPC: Centralized Network Administration for Multi-Project in a large GCP organization?
ANSWER
Implement committed use discounts for predictable workloads, use preemptible VMs for batch jobs, set up budget alerts at the folder level, leverage custom machine types to avoid over-provisioning, and regularly audit usage with cloud intelligence reports. Consider migrating to GKE Autopilot or Cloud Run for containerized workloads to eliminate node management overhead.
01
What is GCP Shared VPC: Centralized Network Administration for Multi-Project and when would you use it in production?
JUNIOR
02
How do you configure GCP Shared VPC: Centralized Network Administration for Multi-Project for high availability across regions?
SENIOR
03
What are the cost optimization strategies for GCP Shared VPC: Centralized Network Administration for Multi-Project in a large GCP organization?
SENIOR
FAQ · 6 QUESTIONS
Frequently Asked Questions
01
Can a service project be attached to multiple host projects?
No, a service project can be attached to only one host project at a time. If you need resources in multiple VPCs, you must use separate service projects or VPC peering between host projects.
Was this helpful?
02
How do I grant a service project access to only specific subnets?
Use IAM conditions on the compute.networkUser role. For example, set a condition that restricts resource.name to a specific subnet pattern like 'projects/HOST_PROJECT/regions/us-central1/subnetworks/app-subnet-*'. This prevents the service project from using other subnets.
Was this helpful?
03
What happens to existing resources when I attach a service project to a Shared VPC?
Existing resources remain in their original VPC. They are not automatically migrated. You must recreate them in the Shared VPC's subnets. Plan for a migration window.
Was this helpful?
04
Can I use Shared VPC with Cloud Run or Cloud Functions?
Yes, but with limitations. Cloud Run (fully managed) supports VPC connectors that can be placed in a Shared VPC subnet. Cloud Functions can use a VPC connector as well. However, the connector must be in the same project as the function or run service, and the subnet must be in the host project. Ensure the connector's service account has compute.networkUser on the subnet.
Was this helpful?
05
How do I troubleshoot connectivity issues between service projects in the same Shared VPC?
Use VPC Flow Logs to see if traffic is being dropped. Use Network Intelligence Center's Connectivity Test to simulate traffic between two VMs and identify blocking firewall rules. Also, check that both VMs are in the same subnet or that routes exist between subnets (they do by default in the same VPC).
Was this helpful?
06
Is there a limit to the number of service projects per host project?
Yes, the default limit is 100 service projects per host project. You can request an increase up to 1000. Also, each host project can have up to 100 VPC networks, but only one can be used as the Shared VPC network per project.