Cloud Networking & VPC - The Private Network Inside the Public Cloud
Helpful context:
- Networking, IP, TCP & HTTP - How Data Gets From Here to There
- Cloud Storage Models - Block, File, and Object Storage
- Security Fundamentals - How Systems Protect Themselves and Their Data
When you spin up a virtual machine in GCP or AWS, it does not go directly onto the public internet. It lives inside a private network - a network that you define, that only your resources can see by default, and that you control: what can communicate with what, what can reach the internet, and what stays entirely isolated.
This private network is the Virtual Private Cloud (VPC). Understanding how it works is not optional if you are building anything that needs to run reliably and securely in a cloud environment. Misconfigured networks are one of the most common sources of both security incidents and mysterious connectivity failures.
The Problem VPCs Solve
In the early days of AWS, before VPCs existed (2006-2009), every EC2 instance went into a flat shared network. Your instances were on the same network as other customers' instances. The only isolation was security groups - firewall rules that controlled which traffic could reach your instances. There was no concept of a private network that only your resources could see.
This was obviously inadequate for serious workloads. A database server and a web server should not be on the same network segment as machines belonging to strangers. The principle of least privilege - give each component access only to what it needs - requires a network topology where isolation is possible.
VPCs, introduced in AWS in 2009 and the default mode of GCP from the start, give you a private network that is logically isolated from other customers' networks. The isolation is enforced by the cloud provider’s networking infrastructure - your instances are physically on shared hardware, but the virtual network layer ensures that traffic from your VPC cannot reach another customer’s VPC and vice versa.
IP Addresses, Subnets, and CIDR
A VPC is defined by an IP address range in CIDR notation. CIDR (Classless Inter-Domain Routing) is a compact way to express a range of IP addresses. The notation 10.0.0.0/8 means: the network with IP address 10.0.0.0, with a prefix length of 8 bits. The first 8 bits are fixed; the remaining 24 bits can vary. That is $2^{24} = 16{,}777{,}216$ addresses, from 10.0.0.0 to 10.255.255.255.
A /16 gives you 65,536 addresses. A /24 gives you 256. A /28 gives you 16. In practice, VPCs are often defined as /16 networks (large enough for substantial growth) and divided into subnets.
A subnet is a sub-range of the VPC’s address space, scoped to a single zone. If the VPC is 10.0.0.0/16, you might create:
- Subnet for us-central1-a:
10.0.1.0/24(256 addresses) - Subnet for us-central1-b:
10.0.2.0/24(256 addresses) - Subnet for us-central1-c:
10.0.3.0/24(256 addresses)
Each VM placed in a zone gets an IP address from that zone’s subnet. VMs in the same subnet can communicate directly. VMs in different subnets in the same VPC can communicate through the VPC’s internal routing.
The key design decision is subnet purpose. It is common to separate:
- Public subnets for resources that need to be internet-accessible (load balancers, NAT gateways)
- Private subnets for resources that should only be accessible from inside the network (databases, application servers, Kubernetes worker nodes)
A database in a private subnet has no direct route to or from the internet. An attacker who compromises the public internet cannot directly connect to it - they would first need to compromise something inside the private subnet.
Routing
Within a VPC, traffic between instances is routed by the cloud provider’s virtual network fabric. You do not need to configure routing for intra-VPC traffic; it just works.
Traffic to and from the internet is different. A route table defines where traffic goes based on its destination. Every subnet has a route table. The default route table has:
- A local route: traffic to any address in the VPC goes to the VPC’s internal network
- An internet route (if the subnet is public): traffic to
0.0.0.0/0(all other addresses) goes to the internet gateway
Instances in public subnets have public IP addresses and can communicate directly with the internet. Instances in private subnets cannot be reached from the internet, but they also cannot reach the internet by default - they have no route to the internet gateway. This is usually intentional for databases, but application servers in private subnets still need to reach the internet: to download software updates, call external APIs, pull container images.
The solution is a Cloud NAT (Network Address Translation) gateway. A NAT gateway sits in a public subnet and translates outbound traffic from private instances: the private instance sends a packet to 1.2.3.4, the NAT gateway rewrites the source address to its own public IP, forwards the packet, receives the response, and forwards it back to the private instance. The internet sees only the NAT gateway’s IP, not the private instance’s. Inbound connections from the internet to the private instance are not possible - the NAT gateway does not maintain state for connections it did not initiate.
Firewall Rules
VPC firewall rules control which traffic is allowed into and out of VM instances. They operate on the VPC level (not the subnet level) and apply to VMs based on network tags or service accounts rather than IP addresses.
A firewall rule specifies:
- Direction: ingress (incoming) or egress (outgoing)
- Priority: lower number = higher priority; the first matching rule applies
- Match criteria: source/destination IP ranges, protocols, ports
- Target: which VMs this rule applies to (via network tag or service account)
- Action: allow or deny
Example: to allow HTTP traffic to web servers tagged webserver, create a rule: ingress, priority 1000, source 0.0.0.0/0, TCP port 80, target tag webserver, action allow.
GCP’s implicit default rules deny all ingress and allow all egress. If you have no rules, nothing can reach your instances from outside (including from the internet) and your instances can reach anything. You add allow rules to open specific ports to specific sources.
The tag-based model is useful because it decouples firewall rules from IP addresses. IP addresses change when instances are replaced. Tags persist. A new web server that is tagged webserver automatically inherits the firewall rules for that tag, without needing a firewall rule update.
VPC Peering
By default, two VPCs cannot communicate with each other - even within the same account. If you want resources in VPC A to communicate with resources in VPC B (perhaps because different teams or environments live in different VPCs), you connect them with VPC peering.
A VPC peering connection is a direct, private network connection between two VPCs. Traffic between peered VPCs travels over the cloud provider’s private network backbone, not the public internet. Latency is low, and there are no data transfer costs for traffic within the same region (cross-region peering does incur costs).
The constraint: VPC peering is not transitive. If VPC A peers with VPC B, and VPC B peers with VPC C, VPC A cannot reach VPC C. You would need to also peer A with C. This becomes unwieldy with many VPCs.
Shared VPC
GCP’s Shared VPC (called Transit Gateway in AWS) addresses the scalability problem of peering. Instead of each team having its own VPC and peering them all together, one host project owns the VPC, and multiple service projects (owned by different teams) can use subnets in that VPC.
Resources in different service projects can communicate within the same Shared VPC without peering. Network administration is centralized - the platform team controls the network; individual teams deploy workloads but cannot modify the network configuration. This is the pattern large organizations use to enforce consistent network security policies across many teams without requiring them to manage networking themselves.
Private Service Connect and Private Google Access
Your application running in a private subnet might need to access GCP services - Cloud Storage, BigQuery, Pub/Sub. By default, these services are accessible at public IP addresses. Traffic from a private instance would need to go through the internet to reach them.
Private Google Access enables private subnet instances to reach GCP APIs and services using internal IP addresses rather than routing through the internet. Enable it on the subnet, and instances in that subnet can access storage.googleapis.com over Google’s internal network without a NAT gateway.
Private Service Connect goes further: it lets you create a private endpoint inside your VPC that represents a managed service (including third-party services). Instead of storage.googleapis.com, you reach Cloud Storage at storage.my-project.internal - an IP address inside your VPC. Traffic never traverses the public internet, and the endpoint can be locked down with firewall rules.
Cloud Interconnect
For workloads where internet connectivity is inadequate - too much latency, bandwidth, or security risk - GCP offers direct physical connections.
Dedicated Interconnect is a direct physical connection between your on-premises network and Google’s network at a colocation facility. Traffic flows over a private circuit with no public internet traversal. Suitable for bulk data transfer, latency-sensitive workloads, or compliance requirements that prohibit data traversal over shared internet infrastructure.
Partner Interconnect provides similar benefits through a network service provider (like AT&T or Equinix) rather than a direct connection. Easier to procure than Dedicated Interconnect, slightly higher latency, appropriate for organizations that cannot afford or do not need the capacity of a direct connection.
Cloud VPN is the software-based alternative: an encrypted tunnel over the public internet between your on-premises network and your VPC. Simpler and cheaper than Interconnect, but dependent on public internet reliability and bandwidth.
Summary
| Concept | What it does |
|---|---|
| VPC | Isolated private network for your cloud resources |
| Subnet | IP address range within a VPC, scoped to a zone |
| Route table | Defines where traffic for a destination IP should go |
| Cloud NAT | Enables private instances to initiate outbound internet connections |
| Firewall rules | Allow/deny traffic to VMs by tag, port, and source |
| VPC peering | Private network connection between two VPCs (not transitive) |
| Shared VPC | One host project’s network used by multiple service projects |
| Private Google Access | Private subnet access to GCP services without internet traversal |
| Cloud Interconnect | Dedicated or partnered physical link to Google’s network |
The networking layer is invisible when it works and catastrophic when it does not. A service that cannot reach its database, or a private subnet that is accidentally internet-accessible, or a firewall rule that silently blocks legitimate traffic - all of these are network configuration failures, not application failures, and they are harder to debug precisely because they are invisible to the application. Getting the network design right upfront - separating public and private subnets, applying firewall rules based on tags, using Private Google Access - is much easier than retrofitting it onto a running system.
Read next: