DEV Community

Cover image for VPCs Compared: AWS vs GCP
Nariman Baubekov
Nariman Baubekov

Posted on

VPCs Compared: AWS vs GCP

In Part 1, we built a cloud-agnostic mental model: addresses live in CIDR blocks, blocks live in subnets, subnets get their personality from a route table, DNS turns names into addresses, and NAT lets private resources reach out without letting anything in.

That model is correct on both AWS and GCP. What differs is the implementation — and one difference in particular is big enough that it reshapes how you should think about almost everything else. Let's start there.

The One Difference That Changes Everything

In AWS, a VPC is a regional resource. It lives entirely inside one AWS region. Want resources in us-east-1 and eu-west-1 talking to each other privately? You need two separate VPCs, connected via peering or a Transit Gateway.

In GCP, a VPC is a global resource. One VPC can span every region Google operates. You don't create a new VPC per region — you create subnets in whichever regions you need, all under the same VPC, and they can all reach each other over internal IPs with no peering, no VPN, no extra setup at all.

AWS VPCs are regional and need peering; a GCP VPC is global

This isn't a minor detail — it changes your default architecture. On AWS, "multi-region" is something you deliberately build toward. On GCP, you're already halfway there just by adding a subnet in a new region.

The trade-off: GCP's model is simpler to operate, but a misconfigured firewall rule or an overly broad IAM policy has a wider blast radius, since it can apply globally instead of being contained to one region.

Subnets: AZ-Scoped vs Region-Scoped

This difference cascades directly into subnets:

  • AWS subnets belong to a single Availability Zone. If you want high availability across AZs, you create one subnet per AZ (that's why you'll always see subnet lists in pairs or triples in AWS docs).
  • GCP subnets belong to a single region — but span every zone within it. One subnet in us-central1 automatically covers us-central1-a, -b, and -c. You don't need a subnet per zone for high availability; it's built in.

AWS subnets live in a single AZ; GCP subnets span an entire region

Practical upshot for a data platform: on AWS, spreading a Dataproc-equivalent (EMR) cluster or a database across AZs means explicitly provisioning multiple subnets. On GCP, a single regional subnet already gives you that spread — one less thing to design around.

The Default VPC (Convenient, and Not What You Want in Production)

Both clouds hand you a default network the moment you create an account or project, and both defaults exist purely for convenience, not security.

AWS: every account gets a Default VPC in every region, with a public subnet in each AZ and an Internet Gateway already attached. Deploy an EC2 instance without specifying a VPC, and it lands here — internet-facing by default.

GCP: every project gets a default network with auto-created subnets in every GCP region (roughly 40 of them), plus permissive firewall rules that allow SSH and RDP from anywhere on the internet.

The guidance on both platforms converges on the same answer: fine for a five-minute experiment, not what you want for anything real. For production data infrastructure, build a custom VPC (AWS) or custom-mode network (GCP) where you deliberately choose your CIDR ranges, your subnets, and your firewall rules — rather than inheriting whatever the provider assumed you'd want.

Public vs Private: Same Idea, Genuinely Different Mechanism

Here's a nuance that catches people who learned networking on AWS first: GCP doesn't really have "public subnets" and "private subnets" as a subnet-level concept the way AWS does.

On AWS, "public" is a property of the subnet's route table — if it has a 0.0.0.0/0 → Internet Gateway route, every resource in that subnet is capable of reaching the internet (assuming it also has a public IP and its security group allows it).

On GCP, internet reachability is a property of the individual VM, not the subnet. Every subnet has an implicit system route to the internet by default. What actually determines whether a given instance can reach the internet is:

  1. Whether that specific instance has an external IP assigned to it
  2. What the firewall rules allow

AWS: the subnet's route table decides internet access; GCP: the instance decides

So two VMs in the exact same GCP subnet can have completely different internet reachability, just based on whether each one happens to have an external IP. That's a meaningfully different mental model from AWS, where the subnet itself draws that line.

There's one more wrinkle worth knowing here: a GCP VM with no external IP also can't reach Google's own APIs (Cloud Storage, BigQuery, Pub/Sub) by default, since it has no path to the public internet at all. The fix is a subnet-level setting called Private Google Access, which lets internal-IP-only VMs reach Google APIs over Google's internal network without ever touching the public internet. There's no AWS equivalent to this exact mechanism — the closest analogue is a Gateway VPC Endpoint for S3/DynamoDB, which we'll cover properly in Part 4.

Firewalls: Security Groups + NACLs vs GCP Firewall Rules

AWS gives you two layers: Security Groups (stateful, instance-level, deny-inbound-by-default) and Network ACLs (stateless, subnet-level, allow-all-by-default).

GCP collapses this into one system: VPC firewall rules. A few things make them behave differently from AWS's model:

  • They're stateful, like Security Groups (no need to write matching return-traffic rules).
  • They apply at the VPC level, not the subnet or instance level — but they're enforced individually at each VM, so they act like a distributed firewall that follows your instances around.
  • Instead of targeting instances by security-group membership, GCP rules typically target VMs via network tags or service accounts.
  • Rules have an explicit priority (0–65535, lower wins), and there are two implicit rules always present: deny all ingress (priority 65534) and allow all egress (priority 65535).
AWS Security Groups AWS NACLs GCP Firewall Rules
Scope Instance Subnet VPC (enforced per-instance)
State Stateful Stateless Stateful
Default Deny inbound, allow outbound Allow all Deny all ingress, allow all egress
Targeting Security group membership CIDR range Network tags or service accounts
Rule ordering All rules evaluated Numerical order Priority number, lowest wins

One AWS pattern that has no direct GCP parallel: Security Group chaining, where the RDS security group only accepts traffic from the EC2 security group, which only accepts traffic from the ALB security group. GCP achieves the same layered effect using service-account-based targeting — a rule that only allows traffic from instances running as a specific service account, which ends up doing a very similar job.

NAT: NAT Gateway vs Cloud NAT

Conceptually identical to what we covered in Part 1 — outbound-only internet access for resources with no public IP — but provisioned differently:

  • AWS NAT Gateway: deployed directly into a specific public subnet; you typically deploy one per AZ for high availability, and each one needs its own Elastic IP.
  • GCP Cloud NAT: attached to a Cloud Router, and configured at the region level — one Cloud NAT gateway can cover every subnet in that region, rather than needing one per subnet or per zone.

AWS needs a NAT gateway per AZ; GCP Cloud NAT is regional

Cost-wise, both charge for the gateway's uptime plus data processed — the NAT cost story from Part 1 applies equally to Cloud NAT.

Bastion Hosts: A Quick Preview

Both clouds support the classic bastion host pattern — a single hardened instance in a public subnet that acts as the one deliberate doorway into a private network. And both clouds now offer a more secure alternative that avoids exposing any inbound port at all:

  • AWS: SSM Session Manager
  • GCP: Identity-Aware Proxy (IAP) TCP forwarding

Both let you reach a private instance for administration without a bastion host, an open SSH port, or a public IP anywhere in sight — access is brokered through the cloud provider's IAM instead. We'll cover this properly, alongside the full bastion pattern, in Part 3.

Cheat Sheet: AWS ↔ GCP Terminology

AWS GCP Notes
VPC VPC network AWS: regional. GCP: global
Subnet Subnet AWS: AZ-scoped. GCP: region-scoped
Internet Gateway Default internet gateway (implicit) GCP's is automatic, not a resource you attach
NAT Gateway Cloud NAT GCP's is regional, attached to a Cloud Router
Security Group + NACL Firewall Rules GCP merges both into one stateful, tag/SA-targeted system
Elastic IP Static external IP address Same idea, different name
VPC Peering VPC Peering Similar limitations (no transitive peering) on both
Shared VPC GCP-specific: share subnets across projects. Covered in Part 5
SSM Session Manager Identity-Aware Proxy (IAP) Bastion-free access via IAM. Covered in Part 3

What's Next

Part 3 takes everything above and turns it into an actual architecture: the classic 3-tier VPC — public, private, and data subnets — built out concretely on both platforms, including exactly where and how a bastion host (or its IAM-brokered replacement) fits in as the one narrow doorway into an otherwise sealed-off private tier.

Top comments (0)