In today’s cloud environments, maintaining strong security often means deploying Virtual Machines (VMs) without public IP addresses. While this enhances isolation, it presents a challenge: how do these private VMs access external resources like software repositories, updates, or third-party APIs? Google Cloud’s Cloud NAT (Network Address Translation) Gateway provides an elegant and secure solution, enabling outbound internet connectivity for your internal-only VMs without exposing them directly to the internet. This guide will walk you through setting up Cloud NAT to achieve this essential capability.
Understanding the Need for Cloud NAT
Traditionally, VMs needing internet access would be assigned an external IP. However, for enhanced security and compliance, many architectures require VMs to remain completely private. Cloud NAT bridges this gap, allowing private VMs to initiate connections to the internet. The NAT gateway translates the VM’s internal IP address to a public IP address for outbound traffic, and then routes the response back to the correct internal VM, all without allowing unsolicited inbound connections from the internet.
Step-by-Step Implementation
1. Deploy a Private VM Instance
Our journey begins by establishing a baseline: a Google Cloud VM instance configured to operate solely with an internal IP address. This configuration ensures maximum privacy and security, as the VM is not directly reachable from the public internet. We’ll deploy a machine (e.g., myvm8-internal-only
in us-central1-a
) within a specified subnet, explicitly denying an external IP. After creation, connecting to this VM via IAP (Identity-Aware Proxy) allows us to confirm its isolation. Initial attempts to ping
external websites or install packages will predictably fail, demonstrating the VM’s current lack of outbound internet access.
Example gcloud
commands for VM creation and testing:
gcloud config set project YOUR_PROJECT_ID
gcloud compute instances create myvm8-internal-only \
--zone=us-central1-a \
--machine-type=e2-micro \
--network-interface=subnet=mysubnet1,no-address
gcloud compute ssh --zone "us-central1-a" "myvm8-internal-only" --tunnel-through-iap
# Inside VM:
ping google.com
sudo apt install -y telnet
(Observation: All commands should fail, confirming no internet access.)
2. Create a Cloud Router
The Cloud Router is a foundational component for Cloud NAT, acting as the control plane for your NAT gateway. We’ll provision a new Cloud Router instance (e.g., mycloudrouter1
) within the same region (e.g., us-central1
) and associate it with the VPC network containing our private VM. This router, while not directly forwarding traffic itself, is essential for managing the NAT configuration and facilitating dynamic route propagation.
Configure the Cloud Router via the GCP Console (Network Connectivity -> Cloud Routers -> CREATE ROUTER):
- Name: mycloudrouter1
- Network: vpc2-custom (or your relevant VPC)
- Region: us-central1
- Routes: Default (Advertise all subnets)
3. Configure the Cloud NAT Gateway
With the Cloud Router in place, we proceed to configure the Cloud NAT Gateway itself. This gateway (e.g., mycloudnat1
) will be set up as a ‘Public’ NAT type, linking directly to the previously created Cloud Router in the specified region. Crucially, we define the NAT mapping to include VM instances, ensuring that traffic originating from our private VMs’ primary and secondary IP ranges is eligible for translation. Opting for automatic IP address allocation simplifies management, allowing Google Cloud to handle the public IP addresses used for outbound connections.
Configure Cloud NAT via the GCP Console (Network Services -> Cloud NAT -> GET STARTED):
- Gateway name: mycloudnat1
- NAT Type: Public
- Cloud Router: mycloudrouter1
- Region: us-central1
- Cloud NAT mapping:
- Source endpoint type: VM Instances
- Source: Primary and Secondary ranges for all subnets
- Cloud NAT IP Address: Automatic
- Network Service Tier: Premium
4. Verify Outbound Internet Access
After deploying the Cloud NAT Gateway, a brief waiting period (typically 2-3 minutes) allows the configuration to propagate. Reconnecting to our internal-only VM, we can now re-run our connectivity tests. Successful ping
commands to external domains and the ability to install software packages (e.g., apache2
) will confirm that our private VM now has seamless, secure outbound internet access, all without ever possessing a public IP address. The outbound traffic from the VM will be translated by the Cloud NAT Gateway, using its allocated public IP, effectively masking the VM’s internal IP from the internet. You can observe the external IP used by NAT by checking the VPC Networks -> IP Addresses section in your GCP console.
Reconnect and re-test connectivity:
gcloud compute ssh --zone "us-central1-a" "myvm8-internal-only" --tunnel-through-iap
# Inside VM (after 2-3 mins):
ping google.com
sudo apt install -y apache2
(Observation: All commands should now succeed, confirming internet access.)
Cleanup Resources
Once you’ve completed your testing or no longer require this setup, it’s good practice to clean up the resources to avoid incurring unnecessary costs. This involves deleting the VM instance, the Cloud NAT Gateway, and the associated Cloud Router.
Use the following gcloud
commands or delete via the Console:
# Delete VM
gcloud compute instances delete myvm8-internal-only --zone=us-central1-a --delete-disks=all
# Delete Cloud NAT Gateway and Cloud Router via Console:
# Network Services -> Cloud NAT -> Delete mycloudnat1
# Network Connectivity -> Cloud Routers -> Delete mycloudrouter1
Conclusion
By leveraging Google Cloud’s Cloud NAT Gateway, you can effectively provide outbound internet access to your private VM instances, maintaining a robust security posture while ensuring your applications can perform necessary updates and communicate with external services. This setup is crucial for building secure and compliant cloud architectures on GCP.