Assumes you're comfortable with Part 1's "one global VPC" framing — this chapter builds the full VPC design, security, and traffic-management picture on top of that foundation. A deeper GCP Network Engineering course (this site's Professional Cloud Network Engineer track) picks up everything past ACE scope.
Table of Contents#
- What This Chapter Covers
- VPC Networks and Subnets
- Auto Mode vs. Custom Mode VPCs
- Shared VPC — Centralized Networking Across Projects
- VPC Network Peering
- Cloud NGFW: Firewall Rules and Firewall Policies
- Tags and Service Accounts in Firewall Targeting
- Static and Ephemeral IP Addresses
- Cloud NAT — Outbound Internet Without a Public IP
- Custom Static Routes
- Choosing a Load Balancer
- Cloud DNS — Public and Private Zones
- Cloud CDN
- Network Service Tiers
- Connecting to On-Premises: VPN and Interconnect
- Private Google Access and Private Service Connect
- VPC Flow Logs
- A Full Worked Example: Meridian's Network Design End to End
- Real-World Scenario: The Firewall Rule That Blocked the Health Check
- Networking Terminology Map
- How a Request Actually Reaches shipment-api
- Second Real-World Scenario: The Peering Request That Never Got Approved
- Pre-Flight Checklist: Is This Network Design Production-Ready?
- Common Mistakes and Interview Traps
- Worked Practice Problems
- Summary and What's Next
What This Chapter Covers#
This chapter builds the full VPC networking picture Part 1 only introduced — subnets, firewalls, load balancing, DNS, and the connectivity options linking Meridian's GCP footprint to the outside world, the ACE exam's "planning and implementing networking resources" and "managing networking resources" objectives combined into one coherent design.
🎯 By the end of this chapter, you'll be able to design a VPC with correctly-scoped subnets and firewall rules, choose the right load balancer for a given traffic pattern, and connect a GCP network securely to both the public internet and on-premises infrastructure.
VPC Networks and Subnets#
A VPC network is the global container Part 1 introduced; a subnet is where IP addresses actually get allocated, scoped to one region. Every resource with a network interface — a Compute Engine VM, a GKE node, an internal load balancer — lives in exactly one subnet.
# Create a custom-mode VPC (see the next section for why custom,
# not auto, is Meridian's default) and a subnet in each region
# the company actually operates in
gcloud compute networks create meridian-vpc --subnet-mode=custom
gcloud compute networks subnets create meridian-subnet-us-central1 \
--network=meridian-vpc --region=us-central1 --range=10.0.0.0/20
gcloud compute networks subnets create meridian-subnet-us-east1 \
--network=meridian-vpc --region=us-east1 --range=10.0.16.0/20Subnet IP ranges are worth planning deliberately from the start — resizing a subnet later is possible but adds real friction, and non-overlapping ranges across regions (and across any network Meridian might eventually peer or connect with) avoid a real routing conflict down the line.
Auto Mode vs. Custom Mode VPCs#
| Mode | Subnet creation | Reach for it when... |
|---|---|---|
| Auto mode | GCP creates one subnet per region automatically, with predefined ranges | A quick prototype or sandbox where subnet planning isn't worth the setup time |
| Custom mode | You explicitly create each subnet, with ranges you choose | Any real production network — Meridian's default from day one |
Tip
Best practice: use custom mode for every production VPC, full stop. Auto mode's convenience trades away exactly the deliberate IP planning a growing network needs — a company that starts on auto mode and later needs custom ranges (for a VPN, an acquisition, or simply outgrowing the predefined ranges) faces a real migration, not a simple settings change.
Shared VPC — Centralized Networking Across Projects#
Shared VPC lets a single VPC network, owned by one "host" project, be used by resources in multiple other "service" projects — the mechanism that reconciles Part 1's project-per-environment discipline with the fact that all those projects still need to talk to each other over a consistent network.
# Designate meridian-shared-networking (from Part 1's landing zone)
# as the Shared VPC host project
gcloud compute shared-vpc enable meridian-shared-networking
# Attach service projects — meridian-shipment-prod's VMs and GKE
# nodes now use the host project's VPC and subnets directly
gcloud compute shared-vpc associated-projects add meridian-shipment-prod \
--host-project=meridian-shared-networkingThis is exactly the meridian-shared-networking project Part 1's landing zone bootstrap created without yet explaining its purpose — Shared VPC is that purpose: one team (Devon's) owns and secures the network centrally, while application-owning projects (meridian-shipment-prod) consume subnets from it without needing their own separate VPC or duplicated firewall policy.
Devon's team owns and secures the network once, centrally, in the host project — every service project consumes the same subnets without duplicating firewall policy or IP planning.
VPC Network Peering#
Peering connects two separate VPC networks so resources in each can communicate using internal IPs, without traffic crossing the public internet — a different mechanism from Shared VPC, worth distinguishing clearly since both solve "let two things on GCP talk to each other privately."
| Mechanism | Networks stay separate? | Centralized management? | Reach for it when... |
|---|---|---|---|
| Shared VPC | No — service projects use the host's actual network | Yes — one team manages the network for everyone | Projects under common ownership needing a consistent, centrally-managed network |
| VPC Peering | Yes — each network keeps its own independent management | No — each side manages its own network | Two genuinely separate networks (different teams, or even different organizations) that need connectivity without merging administration |
gcloud compute networks peerings create meridian-to-partner \
--network=meridian-vpc \
--peer-project=partner-logistics-co \
--peer-network=partner-vpcNote
Peering is not transitive — if network A peers with B, and B peers with C, A cannot reach C through B unless A and C also peer directly. This surprises engineers expecting peering to behave like routing more generally does.
Cloud NGFW: Firewall Rules and Firewall Policies#
Cloud Next Generation Firewall (Cloud NGFW) is GCP's firewall system — VPC firewall rules for basic allow/deny, and firewall policies for more advanced, centrally-managed rule sets that can be applied hierarchically across the resource hierarchy.
# A basic VPC firewall rule — allow the load balancer's health
# checks to reach shipment-api backends
gcloud compute firewall-rules create allow-health-checks \
--network=meridian-vpc \
--direction=INGRESS \
--action=ALLOW \
--rules=tcp:8080 \
--source-ranges=35.191.0.0/16,130.211.0.0/22 \
--target-tags=shipment-api-backend# A hierarchical firewall policy, applied at the ORGANIZATION level
# — enforces a baseline no matter which project's firewall rules exist
gcloud compute firewall-policies create meridian-baseline-policy \
--organization=847213590482
gcloud compute firewall-policies rules create 1000 \
--firewall-policy=meridian-baseline-policy \
--action=DENY --direction=INGRESS \
--src-ip-ranges=0.0.0.0/0 --layer4-configs=tcp:22 \
--global-firewall-policyVPC firewall rules and firewall policies are evaluated together, with firewall policies (especially at the organization/folder level) taking precedence — the network-layer equivalent of Part 1's org policies overriding project-level configuration.
Tags and Service Accounts in Firewall Targeting#
Firewall rules target instances via network tags (Part 1's own tags-vs-labels distinction, revisited here at the point it actually matters) or via a service account — the latter is the more precise, IAM-tied option worth preferring where possible:
# Target by service account instead of a network tag — ties
# firewall targeting to the same identity Part 3 already governs
# via IAM, rather than a separately-managed tag string
gcloud compute firewall-rules create allow-shipment-api-egress \
--network=meridian-vpc \
--direction=EGRESS --action=ALLOW \
--rules=tcp:5432 \
--target-service-accounts=shipment-api@meridian-shipment-prod.iam.gserviceaccount.com \
--destination-ranges=10.0.0.0/20Tip
Best practice: prefer targeting firewall rules by service account over network tags wherever both would work. A network tag is just a string an instance carries — anyone with edit access to the instance can add or remove it. A service account binding is governed by Part 3's IAM system, meaning firewall targeting inherits the same access-control rigor as everything else this course has built.
Static and Ephemeral IP Addresses#
# Reserve a static external IP — needed for anything requiring a
# stable, known address (a DNS A record, an allowlisted partner integration)
gcloud compute addresses create meridian-api-static-ip --region=us-central1
# Reserve a static INTERNAL IP — for a resource other internal
# systems need to reach at a predictable address
gcloud compute addresses create meridian-db-internal-ip \
--region=us-central1 --subnet=meridian-subnet-us-central1 --internalAn ephemeral IP (the default for most resources) changes if the resource is recreated — fine for anything stateless and disposable per Part 4's MIG philosophy, a real problem for anything a DNS record or external partner needs to reference by a stable address.
Cloud NAT — Outbound Internet Without a Public IP#
Cloud NAT provides outbound-only internet access for resources with no public IP — exactly the pattern every --no-address instance and private GKE cluster in this course has depended on without yet explaining the mechanism.
gcloud compute routers create meridian-nat-router \
--network=meridian-vpc --region=us-central1
gcloud compute routers nats create meridian-nat-gateway \
--router=meridian-nat-router --region=us-central1 \
--auto-allocate-nat-external-ips \
--nat-all-subnet-ip-rangesWithout Cloud NAT, every --no-address instance from Part 4 (following Part 1's org policy) would have no way to reach the public internet at all — not even for something as basic as pulling an OS package update. Cloud NAT is what makes "no public IP" and "still functional" compatible, translating outbound traffic through a small pool of shared external IPs without ever exposing an inbound path back to the instance.
Custom Static Routes#
# A custom route — rarely needed for most workloads, since GCP's
# default routes handle standard traffic already, but genuinely
# necessary for specific topologies (routing through a network
# virtual appliance, for instance)
gcloud compute routes create route-via-nva \
--network=meridian-vpc \
--destination-range=192.168.100.0/24 \
--next-hop-instance=network-appliance-1 \
--next-hop-instance-zone=us-central1-aChoosing a Load Balancer#
GCP's load balancer portfolio spans global/regional, external/internal, and Layer 4/Layer 7 — nine meaningful combinations, and picking correctly matters for both cost and capability.
| Need | Load balancer |
|---|---|
| Global HTTP(S) traffic, needs Cloud CDN and WAF integration | Global external Application Load Balancer |
| Regional HTTP(S) traffic, data-residency requirement keeps it in-region | Regional external Application Load Balancer |
| Non-HTTP TCP/UDP traffic (a raw TCP protocol, a game server) | Network Load Balancer (passthrough or proxy) |
| Internal-only traffic between services in the same VPC | Internal Application/Network Load Balancer |
# shipment-api sits behind a global external Application Load
# Balancer — HTTP(S) traffic, benefits from Cloud CDN, no
# data-residency requirement forcing a regional-only design
gcloud compute backend-services create shipment-api-backend \
--global --protocol=HTTPS --port-name=https \
--health-checks=shipment-api-health-checkWarning
A Layer 4 Network Load Balancer has no visibility into HTTP semantics (paths, headers, cookies) — routing decisions based on URL path or header values require an Application Load Balancer. Choosing the wrong tier isn't just a missed feature; it can mean the load balancer simply cannot implement a routing requirement at all, discovered only once the requirement comes up.
Cloud DNS — Public and Private Zones#
# A public zone for meridianlogistics.com's external-facing records
gcloud dns managed-zones create meridian-public-zone \
--dns-name=meridianlogistics.com --description="Public zone"
# A private zone, resolvable only from within meridian-vpc — for
# internal service discovery not meant to be publicly resolvable
gcloud dns managed-zones create meridian-internal-zone \
--dns-name=internal.meridianlogistics.com \
--networks=meridian-vpc --visibility=privateDNS peering (mentioned only briefly here, since it's Part 7's own Network Engineering course's territory) lets one VPC resolve another's private zone — relevant once Meridian's Shared VPC design grows complex enough that service discovery needs to span host and service projects consistently.
Cloud CDN#
# Enable Cloud CDN on the backend service already fronting
# shipment-api's static assets (shipment document thumbnails, say)
gcloud compute backend-services update shipment-assets-backend \
--global --enable-cdn \
--cache-mode=CACHE_ALL_STATICCloud CDN caches content at Google's edge locations, close to end users — a direct latency win for static or infrequently-changing content, and a real cost reduction since cached responses never reach the origin backend at all.
Network Service Tiers#
| Tier | Routing path | Cost | Reach for it when... |
|---|---|---|---|
| Premium | Google's own global private backbone, edge-to-edge | Higher | Default choice — lower latency, higher reliability |
| Standard | Public internet for part of the path | Lower | Cost-sensitive workloads where the latency/reliability difference genuinely doesn't matter |
Meridian runs Premium tier by default for anything customer-facing (shipment-api), matching the network-quality expectations of a customer tracking a real-time shipment, and would only consider Standard tier for a genuinely latency-insensitive internal batch workload.
Connecting to On-Premises: VPN and Interconnect#
| Option | Bandwidth | Setup time | Reach for it when... |
|---|---|---|---|
| Cloud VPN (HA VPN) | Up to ~3 Gbps per tunnel | Minutes to hours | Quick setup, moderate bandwidth need, or as a backup path |
| Dedicated Interconnect | 10-200 Gbps | Weeks (physical circuit provisioning) | Sustained high-bandwidth need, direct physical connection to Google |
| Partner Interconnect | 50 Mbps-50 Gbps | Days to weeks | High bandwidth without Dedicated Interconnect's stricter location requirements |
# HA VPN — Meridian's actual choice, connecting the legacy
# on-premises data center (still hosting a handful of workloads
# mid-migration) to meridian-vpc
gcloud compute vpn-gateways create meridian-onprem-vpn \
--network=meridian-vpc --region=us-central1Meridian's still-mid-migration on-premises footprint uses HA VPN specifically because the remaining bandwidth need is modest and the setup speed mattered more than Dedicated Interconnect's higher ceiling — a decision worth revisiting if the on-premises footprint ever grows rather than shrinks further.
Private Google Access and Private Service Connect#
Private Google Access lets a resource with no public IP still reach Google APIs (Cloud Storage, BigQuery) over Google's internal network — distinct from Cloud NAT, which handles general internet egress; Private Service Connect goes further, letting a service (Google's own, or another organization's, or your own across VPCs) be consumed via a private IP inside your VPC.
gcloud compute networks subnets update meridian-subnet-us-central1 \
--region=us-central1 --enable-private-ip-google-accessVPC Flow Logs#
gcloud compute networks subnets update meridian-subnet-us-central1 \
--region=us-central1 --enable-flow-logsFlow logs record metadata (not payload content) for every connection through a subnet — genuinely useful for security investigation and traffic analysis, at a real logging-volume cost worth being deliberate about enabling broadly versus scoping to specific subnets that need it.
A Full Worked Example: Meridian's Network Design End to End#
# 1. Custom-mode Shared VPC in the shared-networking host project
gcloud compute networks create meridian-vpc --subnet-mode=custom \
--project=meridian-shared-networking
gcloud compute shared-vpc enable meridian-shared-networking
# 2. Subnets per region, Private Google Access enabled
gcloud compute networks subnets create meridian-subnet-us-central1 \
--network=meridian-vpc --region=us-central1 --range=10.0.0.0/20 \
--enable-private-ip-google-access --enable-flow-logs
# 3. Attach service projects
gcloud compute shared-vpc associated-projects add meridian-shipment-prod \
--host-project=meridian-shared-networking
# 4. Firewall policy baseline at the org level, specific rules
# targeted by service account within each project
gcloud compute firewall-policies rules create 1000 \
--firewall-policy=meridian-baseline-policy \
--action=DENY --direction=INGRESS --src-ip-ranges=0.0.0.0/0 \
--layer4-configs=tcp:22 --global-firewall-policy
# 5. Cloud NAT for outbound access from no-public-IP instances
gcloud compute routers nats create meridian-nat-gateway \
--router=meridian-nat-router --region=us-central1 \
--auto-allocate-nat-external-ips --nat-all-subnet-ip-ranges
# 6. Global external Application Load Balancer for shipment-api,
# with Cloud CDN for static assets, Premium network tierReal-World Scenario: The Firewall Rule That Blocked the Health Check#
Devon added a tightly-scoped firewall rule allowing only shipment-api's own service account traffic on port 8080 — reasonable, following this chapter's own service-account-targeting best practice — and the load balancer immediately marked every backend unhealthy. The health check itself comes from Google's own load-balancer infrastructure, using the specific IP ranges shown in this chapter's firewall example (35.191.0.0/16 and 130.211.0.0/22), not from shipment-api's service account identity at all — a source Devon's rule never accounted for, since it only permitted the application's own service account as a source. The fix was adding a second, explicit rule allowing those specific health-check ranges, separate from the service-account-scoped application traffic rule.
Warning
Load-balancer health checks originate from Google's own infrastructure IP ranges, not from any identity a firewall rule's --target-service-accounts or tag-based source can match — always include an explicit allow rule for the health-check ranges shown in this chapter's example alongside any application-traffic rule, or a correctly-scoped security rule silently breaks the load balancer it's meant to protect.
Networking Terminology Map#
| Concept | GCP | AWS | Azure |
|---|---|---|---|
| Software-defined network | VPC (global by default) | VPC (regional) | Virtual Network (regional) |
| Centralized multi-project networking | Shared VPC | (no direct equivalent — Transit Gateway is closer to peering-at-scale) | Virtual WAN / hub-and-spoke |
| Private connectivity between networks | VPC Peering | VPC Peering | VNet Peering |
| Outbound-only internet for private resources | Cloud NAT | NAT Gateway | Azure NAT Gateway |
| Layer 7 load balancer | Application Load Balancer | Application Load Balancer (ALB) | Application Gateway |
| Dedicated physical connection | Dedicated/Partner Interconnect | Direct Connect | ExpressRoute |
The global-vs-regional VPC distinction from Part 1 remains the sharpest divergence in this table — every other row maps fairly directly, but "one VPC spans every region automatically" has no clean AWS or Azure equivalent, since both of those platforms scope their base network construct to a single region by design.
How a Request Actually Reaches shipment-api#
Tying several of this chapter's mechanisms together as a single flow, worth seeing end to end rather than as separate isolated pieces:
Every layer this chapter covered — load balancing, CDN, firewall policy — sits on the request path in a specific, ordered way, not as independent, unrelated features.
Second Real-World Scenario: The Peering Request That Never Got Approved#
When Meridian began integrating with the acquired regional courier mentioned in earlier chapters, Devon's team requested a VPC Peering connection between meridian-vpc and the courier's own network to enable direct, private data exchange during the integration period. Peering requires both sides to explicitly accept the connection — Devon's request sat in a "pending" state for two weeks because nobody on the courier's much smaller, less GCP-experienced team realized an action was required on their end at all, since nothing in the console UI made the "we're waiting on you" state visually urgent.
The lesson wasn't technical — peering worked exactly as designed once both sides accepted it — it was that a two-sided network operation with no automatic timeout or escalation is a real coordination risk with an external, less-experienced partner, not just an internal team. Meridian's fix for future partner integrations was a documented checklist item: confirm the counterparty knows to explicitly accept a peering request, and set a calendar follow-up if it hasn't shown as active within 48 hours — the same explicit-ownership-and-checked-follow-up discipline this course applied to break-glass access and policy exceptions, applied here to a cross-organization technical handshake.
Pre-Flight Checklist: Is This Network Design Production-Ready?#
- VPC created in custom mode, with deliberately planned, non-overlapping subnet ranges
- Shared VPC used for centralized network ownership across projects under common management
- Firewall rules target by service account where possible, network tags only where a service account isn't feasible
- An explicit firewall rule allows the load-balancer health-check IP ranges
- Cloud NAT configured for every subnet with no-public-IP resources
- Load balancer tier (Layer 4 vs. 7, global vs. regional) matches the actual traffic and routing requirement
- Private Google Access enabled on every subnet with no-public-IP resources needing Google API access
- VPC Flow Logs enabled at least on subnets carrying sensitive or security-relevant traffic
Common Mistakes and Interview Traps#
| Mistake | Why it happens | The fix |
|---|---|---|
| Starting on auto-mode VPC for a production network | Convenient at setup time | Custom mode from day one — migrating later is a real, avoidable friction |
| Forgetting the health-check IP range firewall rule | A service-account-scoped rule looks complete | Health checks come from Google's own infrastructure ranges — always add them explicitly |
| Confusing VPC Peering with Shared VPC | Both solve "private connectivity between GCP resources" | Peering keeps networks separately managed; Shared VPC centralizes one network across projects |
| Assuming peering is transitive | Feels like normal network routing | A peers with B, B peers with C — A cannot reach C without a direct A-C peering |
| Choosing a Network Load Balancer for HTTP path-based routing | Layer 4 vs. 7 distinction feels academic | Only an Application Load Balancer can route on HTTP semantics — check requirements before choosing the tier |
| Targeting firewall rules by network tag when a service account would work | Tags feel simpler | Service-account targeting inherits Part 3's IAM rigor — a tag is just a string anyone with instance-edit access can change |
Worked Practice Problems#
1. Meridian's shipment-api backends fail their load balancer health check immediately after a new, correctly-scoped firewall rule is deployed limiting inbound traffic to the service's own service account. What's the most likely cause, and what's the fix?
The health check traffic itself originates from Google's own load-balancer infrastructure IP ranges, not from any application identity — a firewall rule scoped only to the application's service account never permits the health-check source at all. The fix is adding a second, explicit rule allowing the documented health-check IP ranges (35.191.0.0/16 and 130.211.0.0/22) alongside the application-traffic rule, not loosening the application rule itself.
2. Two teams at Meridian want their projects to communicate privately, but each team insists on independently managing its own network configuration and firewall policy. Should this use Shared VPC or VPC Peering, and why?
VPC Peering — Shared VPC requires a single host project's network to be used (and therefore centrally managed) by all attached service projects, which conflicts directly with each team wanting independent network management. Peering connects two genuinely separate, independently-managed VPCs, letting each team keep full control of its own firewall policy and configuration while still enabling private connectivity between the two networks.
3. A workload needs to route HTTP traffic based on the request's URL path to different backend services. A colleague suggests a Network Load Balancer since "it's cheaper." What's wrong with that suggestion?
A Network Load Balancer operates at Layer 4 and has no visibility into HTTP-layer semantics like URL paths — it cannot implement path-based routing at all, regardless of cost. This requirement can only be met by an Application Load Balancer (Layer 7), which understands HTTP requests well enough to route based on path, headers, or other request content. Cost is the wrong axis to evaluate here — the Network Load Balancer simply lacks the capability the requirement needs.
4. Meridian's compliance team wants to guarantee that even a firewall-rule misconfiguration at the project level can never accidentally expose SSH access to the internet, org-wide. Which mechanism from this chapter provides that guarantee, and why doesn't a well-written project-level firewall rule alone provide it?
A hierarchical firewall policy applied at the organization level, denying inbound SSH from 0.0.0.0/0, provides this guarantee — evaluated alongside (and, per this chapter, taking precedence over) any project-level VPC firewall rule, the same override relationship Part 1's org policies have over project-level configuration. A well-written project-level rule only protects the one project it's written for; it provides no guarantee against a different, future project being misconfigured, since each project's firewall rules are independent unless a policy above them enforces a baseline everywhere.
5. route-optimizer on GKE needs to call the BigQuery API without a public IP on any cluster node. What's the specific mechanism that makes this possible, and how does it differ from Cloud NAT?
Private Google Access, enabled on the subnet, is the specific mechanism — it lets resources with no public IP reach Google APIs (BigQuery, Cloud Storage, and others) over Google's internal network. This differs from Cloud NAT, which provides general outbound internet access for arbitrary destinations (an external package repository, a third-party API) — Private Google Access is scoped specifically to Google's own API surface and doesn't require translating traffic through NAT gateway IPs at all, a narrower but more direct path for the specific "reach a Google API" need.
Summary and What's Next#
This chapter built GCP's full networking picture: VPC and subnet design, Shared VPC and Peering as two different ways to connect projects, Cloud NGFW's firewall rules and policies, load balancer selection, Cloud DNS, CDN, and the on-premises connectivity options connecting Meridian's remaining legacy footprint to its GCP network. Meridian's network design — a Shared VPC host managed centrally by Devon's team, custom-mode subnets with deliberate IP planning, and firewall rules scoped by service account — demonstrates every principle from earlier chapters (IAM-tied access control, deliberate resource planning, defense against a specific documented failure mode) applied one layer down at the network itself.
Part 8, the final chapter of this course, covers monitoring, logging, and day-2 operations — Cloud Monitoring, Cloud Logging, and the diagnostic tools that turn everything this course has built into something observable and operable in production, not just correctly configured on paper.