Alright, let us talk about networking in Google Cloud. This is where everything connects. You can have the best VMs, the best databases, the most optimized containers — but if your network is not set up right, none of it matters. Everything communicates over the network, and as a cloud architect, you need to understand how to build it properly.
I am going to walk you through the entire networking stack the way I think about it. We will start from scratch — literally, an empty VPC — and build it up step by step, solving problems as they come up.
Virtual Private Cloud — Your Private Plot of Land
Before you deploy anything, you need a network. In Google Cloud, that network is called a VPC (Virtual Private Cloud). Think of it as your own private plot of land inside Google’s massive global infrastructure. It is a logically isolated section where you launch and run your resources.
Now here is what makes GCP’s VPC different from other cloud providers: it is global. A single VPC can span all Google Cloud regions worldwide. That means a VM in us-east1 and a VM in asia-south1 can communicate with each other using private internal IP addresses, as if they were sitting next to each other. No VPN needed between your own regions. This is a huge advantage when you are building global applications.
Auto Mode vs. Custom Mode VPCs
When you create a project, you get a choice:
Auto Mode — This is the easy button. Google automatically creates one subnet in every region with predefined IP ranges. It also creates default firewall rules that allow SSH, RDP, and ICMP. Great for learning and quick prototypes.
Custom Mode — This is what you use in production. You start with nothing. No subnets, no firewall rules. You define everything yourself — which subnets, in which regions, with which IP ranges.
Why custom? Because in production, you do not want a subnet in every single region. And you definitely do not want the pre-canned IP ranges from auto mode — they can conflict with your corporate network when you set up a VPN later.
# Create a custom VPC — the --subnet-mode=custom is the key
gcloud compute networks create my-custom-vpc --subnet-mode=custom
Output:
Created [https://www.googleapis.com/compute/v1/projects/my-project/global/networks/my-custom-vpc].
NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4
my-custom-vpc CUSTOM REGIONAL
From here on, I am going to assume we are working with a custom VPC.
Subnets — Carving Out Your IP Space
So we have our global VPC. But you cannot just drop a VM into the VPC directly — you need a subnet. A subnet is a regional resource. It is a defined range of IP addresses within a specific region. When you launch a VM, you place it in a subnet, and it gets its internal IP from that subnet’s range.
# Create a subnet in us-central1 for web servers
# 10.1.2.0/24 gives us ~254 usable IPs
gcloud compute networks subnets create web-subnet-us-central \
--network=my-custom-vpc \
--range=10.1.2.0/24 \
--region=us-central1
Output:
Created [https://www.googleapis.com/compute/v1/projects/my-project/regions/us-central1/subnetworks/web-subnet-us-central].
NAME REGION NETWORK RANGE
web-subnet-us-central us-central1 my-custom-vpc 10.1.2.0/24
It has to be noted that Google reserves the first two and last two IPs in every subnet range for networking purposes. So .0, .1, .254, and .255 are off-limits.
Firewall Rules — Controlling What Gets In and Out
Now we have a VM sitting in our subnet. By default, it is completely isolated. Nothing can reach it, and it cannot reach anything. Secure? Yes. Useful? No. We need firewall rules.
GCP firewall rules are stateful. This is important. If you allow an incoming connection, the return traffic for that same connection is automatically allowed. You do not need a matching egress rule for the response.
A firewall rule has these key components:
- Direction — Ingress (incoming) or Egress (outgoing)
- Action — Allow or Deny
- Source/Destination — IP CIDR range, network tag, or service account
- Protocols and Ports — Like
tcp:80for HTTP,tcp:443for HTTPS,icmpfor ping - Priority — A number from 0 to 65535. Lower number = higher priority. First match wins.
Every VPC has two implied rules you cannot see but can override: an egress allow-all (priority 65535) and an ingress deny-all (priority 65535).
The Power of Network Tags
Let me show you a practical pattern. We want to allow SSH (port 22) to all our backend servers, but only from a specific admin IP. Instead of creating rules per VM, we use network tags.
# Create a firewall rule targeting VMs with the "backend-server" tag
gcloud compute firewall-rules create allow-ssh-from-admin \
--network=my-custom-vpc \
--allow=tcp:22 \
--source-ranges=73.54.12.98/32 \
--target-tags=backend-server \
--priority=1000
# When creating a VM, apply the tag
gcloud compute instances create my-backend-vm \
--network=my-custom-vpc \
--subnet=web-subnet-us-central \
--tags=backend-server
Now any VM with the backend-server tag automatically inherits this firewall rule. Remove the tag, and the VM loses SSH access. Dynamic and scalable. Using service accounts as the source/target is even more secure — it ties permissions to an identity rather than a string label.
Routes — How Packets Find Their Way
How does a packet from a VM in us-central1 know how to reach a VM in europe-west2? Through routes. A route tells the network where to send traffic destined for a specific IP range.
Your VPC comes with system-generated routes:
– A route for each subnet, so VMs within the VPC can find each other
– A default route (0.0.0.0/0) pointing to the internet gateway — this is how your VMs reach the public internet
You generally do not need to manage routes manually unless you are doing something advanced like setting up a VPN or custom routing through a network appliance.
Cloud NAT — Outbound Internet Without Public IPs
Here is a common problem. Your backend VMs need to download software updates and security patches from the internet. The default route allows this, but only if the VM has a public IP address. And giving public IPs to backend servers is a security risk.
Cloud NAT solves this. It is a managed service that lets VMs with only private IPs access the internet for outbound connections. Inbound connections from the internet are NOT possible through NAT — it is egress-only.
# Step 1: Create a Cloud Router (required by NAT)
gcloud compute routers create my-router \
--network=my-custom-vpc \
--region=us-central1
# Step 2: Create the NAT gateway
gcloud compute nats create my-nat-gateway \
--router=my-router \
--region=us-central1 \
--nat-all-subnet-ip-ranges
Now all private VMs in us-central1 subnets can reach the internet without public IPs. Clean and secure.
Important: Cloud NAT is regional. If you have VMs in multiple regions that need outbound internet, you need a NAT gateway in each region.
VPN and Interconnect — Connecting to On-Premises
Your cloud deployment is growing, and now you need to connect it to your on-premises data center. You have two main options:
Cloud VPN
Creates an encrypted IPsec tunnel between your on-prem VPN gateway and a Google Cloud VPN gateway. Traffic goes over the public internet but is encrypted. HA VPN is the recommended option — it provides 99.99% SLA using two tunnels. Quick to set up and cost-effective.
Cloud Interconnect
When you need higher bandwidth, lower latency, and more reliability than a VPN can provide, you go with a direct physical connection.
- Dedicated Interconnect — A private 10 Gbps or 100 Gbps connection directly to Google’s network. Highest performance, highest cost, takes time to provision.
- Partner Interconnect — Connect through a supported service provider. More flexibility (50 Mbps to 50 Gbps) and easier to set up.
The trade-off is straightforward: VPN for standard workloads and flexibility, Interconnect for enterprise-grade, mission-critical connectivity that demands high performance.
VPC Peering — Connecting Two VPCs
Your organization has multiple teams, each with their own project and VPC. The data science team in vpc-analytics needs to access a dataset in vpc-production. How do you connect them?
VPC Peering lets two VPCs communicate using internal IP addresses as if they were on the same network. Firewall rules in each VPC still apply, so you maintain full security control.
# Peering must be set up from BOTH sides
# From network A's side
gcloud compute networks peerings create peer-a-to-b \
--network=net-a \
--peer-network=net-b \
--peer-project=project-b-id
# From network B's side
gcloud compute networks peerings create peer-b-to-a \
--network=net-b \
--peer-network=net-a \
--peer-project=project-a-id
Critical thing to remember: Peering is non-transitive. If VPC-A peers with VPC-B, and VPC-B peers with VPC-C, VPC-A cannot talk to VPC-C. You need a direct peering connection between A and C. Also, there must not be overlapping IP address ranges between peered VPCs — that would cause IP conflicts.
Shared VPC — Enterprise-Scale Networking
If you have dozens of projects and VPCs, managing all the peering connections becomes a nightmare. Shared VPC is the enterprise solution.
You designate one project as the Host Project. This project owns the VPC, subnets, routes, and firewall rules. Then you share subnets with other Service Projects. The resources in service projects can use the shared subnets and communicate with each other, all managed centrally from the host project.
This lets a central network team enforce security and networking policies while giving development teams autonomy over their own resources in service projects. It is the standard for GCP networking at scale.
Cloud DNS — Names Instead of Numbers
Remembering 10.1.2.5 is hard. Remembering web-server-prod-1 is easy. Cloud DNS is Google’s managed DNS service that translates domain names into IP addresses.
- Public Zones — Manage public DNS records for your domains, making services available on the internet
- Private Zones — Internal domain names resolvable only within your VPC. Perfect for service discovery — your backend can find services at
database.internal.prodinstead of hardcoded IPs
Common Pitfalls and Best Practices
VPC and Subnets
– Pitfall: Using Auto Mode VPC in production. The predefined IP ranges will conflict with your corporate network when you set up VPN.
– Best Practice: Always use Custom Mode for production. Plan your IP CIDR ranges carefully.
Firewall Rules
– Pitfall: Creating overly permissive rules (e.g., 0.0.0.0/0 for SSH). Massive security risk.
– Best Practice: Be as specific as possible with source ranges, protocols, and ports. Use network tags or service accounts for targets.
Cloud NAT
– Pitfall: Forgetting that NAT is regional. VMs in different regions need separate NAT gateways.
– Best Practice: Place the NAT gateway in the same region as the VMs using it.
VPC Peering
– Pitfall: Forgetting peering is non-transitive and getting confused about why indirectly connected VPCs cannot communicate.
– Best Practice: For complex topologies, use Shared VPC instead of building a mesh of peering connections.
IAM for Networking
– Pitfall: Giving developers compute.networkAdmin, which lets them change firewall rules and other critical settings.
– Best Practice: Separate roles. Network team gets roles/compute.networkAdmin. Security team gets roles/compute.securityAdmin. Developers get roles/compute.instanceAdmin.
Quick Reference Command Center
# -- VPC --
gcloud compute networks create [VPC_NAME] --subnet-mode=custom
gcloud compute networks list
# -- Subnets --
gcloud compute networks subnets create [SUBNET] \
--network=[VPC] --region=[REGION] --range=[CIDR]
# Enable Private Google Access (VMs with no public IP can reach Google APIs)
gcloud compute networks subnets update [SUBNET] \
--region=[REGION] --enable-private-ip-google-access
# -- Firewall Rules --
gcloud compute firewall-rules create allow-http-web \
--network=[VPC] --direction=INGRESS --priority=1000 \
--action=ALLOW --rules=tcp:80,tcp:443 \
--source-ranges=0.0.0.0/0 --target-tags=web-server
# -- Cloud NAT --
gcloud compute routers create [ROUTER] --network=[VPC] --region=[REGION]
gcloud compute nats create [NAT] --router=[ROUTER] \
--region=[REGION] --nat-all-subnet-ip-ranges
# -- VPC Peering (both sides required) --
gcloud compute networks peerings create peer-a-to-b \
--network=net-a --peer-network=net-b --peer-project=[PROJECT_B]
# -- VMs with networking flags --
gcloud compute instances create my-vm \
--zone=us-central1-a --network=[VPC] \
--subnet=[SUBNET] --tags=web-server
# VM with no public IP (private only)
gcloud compute instances create my-private-vm \
--zone=us-central1-a --subnet=[SUBNET] --no-address

