Cloud NAT
Service 21

Cloud NAT

NetworkManaged

Cloud NAT is the managed Network Address Translation service for VMs without public IPs. It is the keystone of the "no public IPs anywhere" pattern: VMs live on private subnets, all outbound internet traffic exits through Cloud NAT, and the public IP attack surface drops to zero. The mechanism sounds simple; the nuances are in port allocation, the choice of static versus dynamic IPs, and knowing when Cloud NAT is the wrong tool entirely.

Cloud NAT is a regional service. Each region of a VPC needs its own NAT gateway, or its outbound traffic has no way out without a public IP on the VM itself.

Outbound Connectivity Without Public IPs

A VM on a Cloud NAT-enabled subnet can initiate outbound connections to the internet (and to managed services that require public IPs to reach), even though it has no external IP itself. Inbound connections from the internet remain impossible — Cloud NAT is one-way, by design. The net effect: workloads stay invisible from the outside, while still able to call public APIs, fetch packages, and ping third-party services. Cloud NAT works seamlessly with private workloads in Compute Engine, GKE, Cloud Run, App Engine, and any other compute layer that runs on top of a VPC subnet.

Port Allocation

Default 64 portsper VM
VM
65th connection fails
Silent scaling wall. Each outbound connection takes a port. Past the allocation, new connections just fail — symptom is "intermittent errors" with no app-level cause.
Higher allocatione.g. 1024 ports
VM
handles the concurrency
Size to peak concurrent connections. Raise minimum ports per VM (or enable dynamic port allocation) for high fan-out outbound workloads.

Every outbound NAT connection consumes a source port. Cloud NAT allocates port ranges per VM from the gateway's IP pool. The defaults — typically 64 ports per VM — are fine for low-traffic workloads. A workload that opens many concurrent connections (a scraper, a CI runner pulling from many registries, a microservice fanning out to many third-party APIs) can exhaust its port allocation and start dropping connections. The symptom is intermittent connection failures that correlate with traffic volume but do not match any application-level error. Raise min_ports_per_vm and verify the gateway has enough total port capacity (NAT IPs × 64,512 ports per IP minus reserved ports).

Static vs Dynamic NAT IPs

By default, Cloud NAT allocates external IPs from a Google-managed pool — fast to set up, no IP management on your side, but the IPs can change. When a third-party API requires source-IP allowlisting (banks, government APIs, regulated partners), the dynamic pool will not work: you cannot give the partner an allowlist that drifts. Reserve static external IPs and configure Cloud NAT to use them. Capacity planning matters more in this mode — with fixed IPs, scaling beyond their port budget means adding more IPs.

Cloud NAT vs Private Google Access vs PSC

Cloud NAT — outbound to the public internet (third-party APIs, package registries, SaaS endpoints). The right tool when the destination is genuinely public.

Private Google Access — outbound to Google APIs and services (Cloud Storage, BigQuery, Pub/Sub). Free, faster, and avoids consuming Cloud NAT ports. Enable on every subnet by default.

Private Service Connect — outbound to managed services (Cloud SQL private IP, partner SaaS over PSC) using private IPs in your VPC. The right tool for service-to-service connectivity without exposing either side to the public internet.

NAT Logging

Cloud NAT logs record connection translations: source VM, destination, allocated port, timestamp. Logging is off by default — but in any security investigation involving "what did this VM talk to," NAT logs are the only source of truth, and they cannot be enabled retroactively. Turn them on in production. Translation logs only (not errors-only or no logging) is the right setting for security-relevant subnets.

Single Gateway in a Shared VPC

In a Shared VPC, one Cloud NAT gateway per region serves all service projects attached to that VPC — you do not deploy a gateway per project. This is the operationally correct pattern: the networking team manages a small number of gateways with appropriate capacity, while product teams just attach their workloads. Duplicating gateways per project wastes IP budget and complicates the allowlist story with third parties.

Common Mistakes
  • Assigning public IPs to VMs that do not need them — the entire reason Cloud NAT exists is to make this unnecessary.
  • Default port allocation under a workload that opens many concurrent outbound connections — intermittent drops correlate with traffic volume, mystifying the application team.
  • Dynamic NAT IPs when a third party requires source-IP allowlisting — the allowlist drifts every time IPs rotate.
  • Routing Google API traffic through Cloud NAT instead of Private Google Access — pays for ports and bandwidth that the free path handles directly.
  • NAT logging disabled in production — a security incident exposes the gap exactly when you need the data and cannot retroactively obtain it.
  • Duplicate Cloud NAT gateways per project in a Shared VPC — fragmented allowlists, wasted IPs, unclear ownership.
  • Using Cloud NAT for managed-service connectivity (Cloud SQL, internal partner SaaS) where Private Service Connect would be the correct pattern.
Best Practices
  • Cloud NAT plus Private Google Access on every production subnet. No public IPs on VMs.
  • Right-size min_ports_per_vm based on the workload's expected concurrent outbound connection count. Default 64 is fine for most; high-fanout workloads need much more.
  • Reserve static external IPs when any third party requires source-IP allowlisting. Document the IP-to-purpose mapping somewhere humans look during incidents.
  • Enable Cloud NAT translation logging on production gateways from day one.
  • One Cloud NAT gateway per region in a Shared VPC, owned by the networking team. Service projects attach; they do not deploy their own.
  • Use Private Service Connect for managed-service connectivity, not Cloud NAT.
Comparable services AWS NAT Gateway Azure NAT Gateway

Knowledge Check

What does Cloud NAT enable for VMs without public IPs?

  • Inbound and outbound internet connectivity, equivalent to giving each VM a public IP
  • Outbound internet connectivity only — VMs can initiate calls to public endpoints, but inbound connections from the internet remain impossible
  • Connectivity to Google APIs, but not to third-party public internet endpoints
  • Inbound connectivity from a specific allowlist of public IP ranges, configured per VM so only approved external hosts can open sessions to the instance

A workload starts seeing intermittent outbound connection drops that correlate with traffic volume but match no application-level error. What is the most likely cause?

  • Cloud NAT IPs have been rotated and the application is caching stale DNS
  • Default port allocation is exhausted under high-fanout outbound traffic; raise min_ports_per_vm or add NAT IPs to the gateway
  • VPC firewall rules are rate-limiting outbound connections from the subnet once egress volume crosses a per-rule threshold, silently dropping the excess
  • Negative caching at Cloud CDN is interfering with the responses

When must you use static NAT IPs instead of the default dynamic pool?

  • When the workload exceeds 1000 concurrent outbound connections
  • When a third party requires source-IP allowlisting — dynamic IPs would cause the allowlist to drift
  • When the workload sends UDP traffic, since Cloud NAT can only translate UDP flows when the gateway uses manually reserved static IPs
  • When NAT logging is enabled; logs require stable IP addresses to be useful

Why use Private Google Access instead of routing Google API traffic through Cloud NAT?

  • Cloud NAT cannot resolve Google API hostnames correctly
  • Private Google Access reaches Google APIs over internal paths — free, faster, and does not consume Cloud NAT ports — while still requiring no public IPs on the VM
  • Cloud NAT blocks outbound traffic to Google API endpoints by default for security reasons, so Private Google Access is the only path that can reach them at all
  • Private Google Access supports IPv6 traffic to Google APIs while Cloud NAT is strictly IPv4-only, so dual-stack workloads have no other route available to reach the APIs

In a Shared VPC, how many Cloud NAT gateways should you typically deploy per region?

  • One per service project, so each team owns its NAT egress
  • One per region in the host VPC, owned by the networking team; service projects attach their workloads
  • One per VPC subnet that hosts internet-bound workloads, so each subnet gets its own dedicated egress address pool and port budget
  • One per VM, allocated automatically by the platform

You got correct