Using Cloud NAT NAT rules

Cloud NAT is a powerful tool: with it, Compute Engine and Google Kubernetes Engine (GKE) workloads can access internet resources in a scalable and secure manner, without exposing the workloads running on them to outside access using external IPs.

Cloud NAT features a proxy-less design, implementing NAT directly at the Andromeda SDN layer. As such, there's no performance impact to your workload and it scales effortlessly to many VMs, regions and VPCs.

NAT Rules are an extension to Cloud NAT. The NAT Rules feature in Cloud NAT lets you create access rules that define how Cloud NAT is used to connect to the Internet. Currently NAT Rules support source NAT address selection based on destination address.

Without NAT Rules, a VM with Cloud NAT enabled uses the same set of NAT IP addresses to reach all Internet addresses.

Sometimes, a NAT use-case calls for Cloud NAT to use different source IP addresses for specific destinations. A NAT Rule defines a match and a corresponding action. Once you specify NAT rules, the packet is matched with each NAT rule. If a rule gets matched, then the action corresponding to that match takes place.

For more information please review the Documentation section about NAT Rules .

What you'll learn

  • How to set up a Cloud NAT gateway in preparation for NAT Rules.
  • How to design NAT Rules using Common Expression Language (CEL).
  • How to create NAT Rules and attach them to a NAT Gateway.
  • How to test NAT Rules from an instance.
  • How to update a NAT Gateway's rules.
  • How to delete NAT rules and revert to the default Cloud NAT behavior.

What you'll need

  • Basic knowledge of Google Compute Engine
  • Basic networking and TCP/IP knowledge
  • Basic Unix/Linux command line knowledge
  • It is helpful to have completed a tour of networking in GCP such as the Networking in Google Cloud lab.
  • Understanding of Cloud NAT basics.

To interact with GCP, we will use both the Google Cloud Console and Cloud Shell throughout this lab.

Google Cloud Console

The Cloud Console can be reached at https://console.cloud.google.com.

75eef5f6fd6d7e41.png

Self-paced environment setup

  1. Sign in to Cloud Console and create a new project or reuse an existing one. If you don't already have a Gmail or Google Workspace account, you must create one.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • The Project Name is your personal identifier for this project. As long as you follow its naming conventions, you can use anything you want and can update it at any time.
  • The Project ID must be unique across all Google Cloud projects and is immutable (cannot be changed once set). The Cloud console auto-generates a unique string; usually you don't care what it is. In most codelabs, you'll need to reference the Project ID (and it is typically identified as PROJECT_ID), so if you don't like it, generate another random one, or, you can try your own and see if it's available. Then it's "frozen" once the project is created.
  1. Next, you'll need to enable billing in Cloud Console in order to use Google Cloud resources.

Running through this codelab shouldn't cost much, if anything at all. Be sure to to follow any instructions in the "Cleaning up" section which advises you how to shut down resources so you don't incur billing beyond this tutorial. New users of Google Cloud are eligible for the $300 USD Free Trial program.

Start Cloud Shell

While Google Cloud can be operated remotely from your laptop, in this codelab you will be using Google Cloud Shell, a command line environment running in the Cloud.

From the GCP Console click the Cloud Shell icon on the top right toolbar:

bce75f34b2c53987.png

It should only take a few moments to provision and connect to the environment. When it is finished, you should see something like this:

f6ef2b5f13479f3a.png

This virtual machine is loaded with all the development tools you'll need. It offers a persistent 5GB home directory, and runs on Google Cloud, greatly enhancing network performance and authentication. All of your work in this lab can be done with simply a browser.

For this lab, you will use a Project, and create two VPCs with a subnet in each. You will reserve external IP addresses and then create and configure a Cloud NAT gateway (with a Cloud Router), two producer instances as well a consumer instance. After validating the default Cloud NAT behavior, you will create Cloud NAT custom rules and validate their behavior.

Networking architecture overview:

815147de3de0bd19.png

Let's reserve all external IP addresses to be used in this lab. This will help you write all relevant NAT and firewall rules in both consumer and producer VPC.

From Cloud Shell:

gcloud compute addresses  create nat-address-1 nat-address-2 nat-address-3 producer-address-1 producer-address-2 --region us-east4

Output:

Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-1].
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-2].
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-3].
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-1].
Created [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-2].

Populate the IP addresses that were reserved as environment variables.

export natip1=`gcloud compute addresses list --filter name:nat-address-1 --format="get(address)"`
export natip2=`gcloud compute addresses list --filter name:nat-address-2 --format="get(address)"`
export natip3=`gcloud compute addresses list --filter name:nat-address-3 --format="get(address)"`
export producerip1=`gcloud compute addresses list --filter name:producer-address-1 --format="get(address)"`
export producerip2=`gcloud compute addresses list --filter name:producer-address-2 --format="get(address)"`

No output is expected, but to confirm that the addresses were populated properly. Let's output the values of all environment variables.

$ env | egrep '^(nat|producer)ip[1-3]'

Output:

producerip1=<Actual Producer IP 1>
producerip2=<Actual Producer IP 2>
natip1=<NAT IP 1>
natip2=<NAT IP 2>
natip3=<NAT IP 3>

We will now create the resources for the producer resources. The instances running in the producer VPC will offer the internet-facing service using two public IPs "producer-address-1" and "producer-address-2" .

First let's create the VPC. From Cloud Shell:

gcloud compute networks create producer-vpc --subnet-mode custom

Output:

Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/networks/producer-vpc].
NAME      SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4
producer-vpc  CUSTOM       REGIONAL

Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:

$ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp:22,tcp:3389,icmp

Next, let's create the subnet in us-east4. From Cloud Shell:

gcloud compute networks subnets create producer-e4 \
   --network producer-vpc --range 10.0.0.0/24 --region us-east4

Output:

Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/regions/us-east4/subnetworks/producer-e4].
NAME              REGION       NETWORK       RANGE
producer-e4       us-east4  producer-vpc  10.0.0.0/24

Next, let's create VPC firewall rules to allow the NAT IP addresses to reach the producer instances on port 8080.

For the first rule, from Cloud Shell:

gcloud compute firewall-rules create producer-allow-8080 \
  --network producer-vpc --allow tcp:8080 \
  --source-ranges $natip1,$natip2,$natip3

Output:

Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/firewalls/producer-allow-8080].
Creating firewall...done.
NAME                 NETWORK       DIRECTION  PRIORITY  ALLOW     DENY  DISABLED
producer-allow-8080  producer-vpc  INGRESS    1000      tcp:8080        False

Next step is to create the two producer instances.

The producer instances will run an IP echo service in a docker container available on Docker Hub (source code is available in the service author's GitHub repo.

To quickly provision the instances with all required software, we will use the Container deployment on Compute Engine feature.

To be able to write NAT rules, we will provision each instance with a different reserved IP address.

Create the first instance. From Cloud Shell:

gcloud compute instances create-with-container producer-instance-1 \
--zone=us-east4-a --machine-type=e2-medium \
--network-interface=address=producer-address-1,network-tier=PREMIUM,subnet=producer-e4 \
--container-image=mpolden/echoip --container-restart-policy=always

Output:

Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/zones/us-east4-a/instances/producer-instance-1].
NAME                 ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP  STATUS
producer-instance-1  us-east4-a  e2-medium                  10.0.0.2     <producer IP 1>  RUNNING

Then create the second instance. From Cloud Shell:

gcloud compute instances create-with-container producer-instance-2 \
 --zone=us-east4-a --machine-type=e2-medium \
--network-interface=address=producer-address-2,network-tier=PREMIUM,subnet=producer-e4 \
--container-image=mpolden/echoip --container-restart-policy=always

Output:

Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/zones/us-east4-a/instances/producer-instance-2].
NAME                 ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP  STATUS
producer-instance-2  us-east4-a  e2-medium                  10.0.0.3     <producer IP 2>  RUNNING

Now that you have created the producer service, it's now time to create the consumer VPC and its Cloud NAT gateway.

After creating the VPC and subnet, we will add a simple ingress firewall rule to allow the IAP for TCP source IP ranges. This will allow us to SSH to the consumer instances directly using gcloud.

We will then create a simple Cloud NAT gateway in manual allocation mode and the reserved address "nat-address-1" associated with it. In subsequent parts of the codelab, we will update the gateway's configuration to add custom rules. .

First let's create the VPC. From Cloud Shell:

gcloud compute networks create consumer-vpc --subnet-mode custom

Output:

Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/networks/consumer-vpc].
NAME      SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4
consumer-vpc  CUSTOM       REGIONAL

Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:

$ gcloud compute firewall-rules create <FIREWALL_NAME> --network consumer-vpc --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network producer-vpc --allow tcp:22,tcp:3389,icmp

Next, let's create a subnet in us-east4. From Cloud Shell:

gcloud compute networks subnets create consumer-e4 \
   --network consumer-vpc --range 10.0.0.0/24 --region us-east4

Output:

Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/regions/us-east4/subnetworks/consumer-e4].
NAME              REGION       NETWORK       RANGE
consumer-e4       us-east4  consumer-vpc  10.0.0.0/24

Next, let's create a VPC firewall rules to allow IAP ranges addresses to reach the consumer instances on port 22.

For the first firewall rule, run the following from Cloud Shell:

gcloud compute firewall-rules create consumer-allow-iap \
  --network consumer-vpc --allow tcp:22 \
  --source-ranges 35.235.240.0/20

Output:

Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/global/firewalls/consumer-allow-iap].
Creating firewall...done.
NAME                 NETWORK       DIRECTION  PRIORITY  ALLOW     DENY  DISABLED
consumer-allow-iap  consumer-vpc  INGRESS    1000      tcp:22        False

Before creating a NAT gateway, we need to create a Cloud Router instance first (we use a private ASN number but it's irrelevant for this lab's activities). From Cloud Shell:

gcloud compute routers create consumer-cr \
--region=us-east4 --network=consumer-vpc \
 --asn=65501

Output:

Creating router [consumer-cr]...done.
NAME         REGION       NETWORK
consumer-cr  us-east4  consumer-vpc

Then create the NAT gateway instance. From Cloud Shell:

gcloud compute routers nats create consumer-nat-gw \
    --router=consumer-cr \
    --router-region=us-east4 \
    --nat-all-subnet-ip-ranges \
    --nat-external-ip-pool=nat-address-1

Output:

Creating NAT [consumer-nat-gw] in router [consumer-cr]...done.

Create the consumer test instance. We populate the reserved producer IPs here to be able to refer to them within the instance later. From Cloud Shell:

gcloud compute instances create consumer-instance --zone=us-east4-a \
--machine-type=e2-medium --network-interface=subnet=consumer-e4,no-address \
--metadata=producer-service-ip1=$producerip1,producer-service-ip2=$producerip2

Output:

Created [https://www.googleapis.com/compute/v1/projects/<Project-ID>/zones/us-east4-a/instances/consumer-instance].
NAME               ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP  STATUS
consumer-instance  us-east4-a  e2-medium                  10.0.0.2                  RUNNING

At this point, the consumer instance uses the default Cloud NAT behavior which uses the same reserved IP "nat-address-1" for communicating with all external addresses.

Let's validate this behavior first before making use of the new NAT Rules feature in Cloud NAT.

SSH into the consumer instance. From Cloud Shell:

gcloud compute ssh consumer-instance --zone=us-east4-a

You should be now in the instance shell.

Sample Output (full output truncated for brevity)

No zone specified. Using zone [us-east4-a] for instance: [consumer-instance].
External IP address was not found; defaulting to using IAP tunneling.
...
...
<username>@consumer-instance:~$

From within the consumer instance, let's first fetch both producer IPs and populate them as environment variables

export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"`

export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`

Then try to curl to both producer instances and observe the returned source IP address.

<username>@consumer-instance:~$ curl http://$producerip1:8080
34.136.8.83
<username>@consumer-instance:~$ curl http://$producerip2:8080
34.136.8.83

You should see the same IP address returned for both endpoints, which is equal to the value of external reserved IP "nat-address-1".

Similarly, a curl to any external IP reflector service should show the same IP, for example:

<username>@consumer-instance:~$ curl http://ifconfig.co
34.136.8.83
<username>@consumer-instance:~$ curl http://ifconfig.me
34.136.8.83
<username>@consumer-instance:~$ curl http://ip.fyr.io
34.136.8.83

Exit the instance's SSH session for now, we will SSH back after we have configured NAT Rules.

NAT rules are written using Common Expression Language syntax. For more information about the rule expression language, see Rule expression language.

You can add a NAT rule to an existing NAT gateway using gcloud commands as well. We'll explore both options to create Cloud NAT rules.

First let's create a NAT rule YAML file.

From Cloud Shell:

export projectid=`gcloud config get-value project`

cat <<EOF >natrulesfile.txt
rules:
 - ruleNumber: 100
   match: destination.ip == '$producerip2'
   action:
     sourceNatActiveIps:
     -  /projects/$projectid/regions/us-east4/addresses/nat-address-2
EOF

Then let's update our existing NAT gateway using this rule file. From Cloud Shell:

gcloud alpha compute routers nats update consumer-nat-gw \
    --router=consumer-cr \
    --rules=natrulesfile.txt \
    --router-region=us-east4

You should expect the following output :

Updating nat [consumer-nat-gw] in router [consumer-cr]...done.

Validate that the rule has been successfully configured. From Cloud Shell:

gcloud alpha compute routers nats rules list \
--nat=consumer-nat-gw --router=consumer-cr \
--router-region=us-east4

You should expect the following output :

RULE_NUMBER  MATCH
100          destination.ip == '35.192.142.134'

Let's try and re-create the same rule using gcloud commands only. First delete the existing rule. From Cloud Shell:

gcloud alpha compute routers nats rules delete 100 \
--nat=consumer-nat-gw --router=consumer-cr \
--router-region=us-east4 --quiet

You should expect the following output :

Updated [https://www.googleapis.com/compute/alpha/projects/ghaleb-s2/regions/us-east4/routers/consumer-cr]

Then re-create the rule using this gcloud command. From Cloud Shell:

gcloud alpha compute routers nats rules create 100 \
 --match='destination.ip == "'$producerip2'"' \
--source-nat-active-ips=nat-address-2 --nat=consumer-nat-gw \
 --router=consumer-cr --router-region=us-east4

You should expect the following output :

Creating Rule [100] in NAT [consumer-nat-gw]...done.

Again to validate that the rule was created successfully, repeat the earlier command. This time we will add the YAML formatting switch to see the full details of the rule.

From Cloud Shell:

gcloud alpha compute routers nats rules list\
 --nat=consumer-nat-gw --router=consumer-cr \
--router-region=us-east4  --format=yaml

You should expect the following output :

---
action:
  sourceNatActiveIps:
  - https://www.googleapis.com/compute/alpha/projects/<Project-ID>/regions/us-east4/addresses/nat-address-2
match: destination.ip == <actual IP for producer-IP 2>
ruleNumber: 100

Finally, notice that now both "nat-address1" and "nat-address-2" external addresses show as "IN_USE". To see that, run this command from Cloud Shell:

$ gcloud compute addresses list

You should expect the following output (Actual IP addresses should match the addresses you have reserved) :

NAME                ADDRESS/RANGE   TYPE      PURPOSE  NETWORK  REGION       SUBNET  STATUS
nat-address-1       34.136.8.83     EXTERNAL                    us-east4          IN_USE
nat-address-2       34.70.137.35    EXTERNAL                    us-east4          IN_USE
nat-address-3       34.135.103.88   EXTERNAL                    us-east4          RESERVED
producer-address-1  34.66.0.105     EXTERNAL                    us-east4          IN_USE
producer-address-2  35.192.142.134  EXTERNAL                    us-east4          IN_USE

At this point, the consumer instance should use the created Cloud NAT Rule to use nat-address-2 to communicate with producer-address-2.

Let's validate this behavior. SSH into the consumer instance. From Cloud Shell:

gcloud compute ssh consumer-instance --zone=us-east4-a

You should be now in the instance shell.

Sample Output (full output truncated for brevity)

No zone specified. Using zone [us-east4-a] for instance: [consumer-instance].
External IP address was not found; defaulting to using IAP tunneling.
...
...
<username>@consumer-instance:~$

From within the consumer instance, let's first fetch both producer IPs and populate them as environment variables

export producerip1=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip1" -H "Metadata-Flavor: Google"`

export producerip2=`curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/producer-service-ip2" -H "Metadata-Flavor: Google"`

Then try to curl to both producer instances and observe the returned source IP address.

<username>@consumer-instance:~$ curl http://$producerip1:8080
34.136.8.83
<username>@consumer-instance:~$ curl http://$producerip2:8080
34.70.137.35

You should now see a different IP address being returned for both endpoints, the first IP address should be the same as the default behavior. The second IP address should be equal to "nat-address-2" after the addition of the new NAT rule.

A curl to any external IP reflector service should still show the same IP as the default behavior, for example:

<username>@consumer-instance:~$ curl http://ifconfig.co
34.136.8.83
<username>@consumer-instance:~$ curl http://ifconfig.me
34.136.8.83
<username>@consumer-instance:~$ curl http://ip.fyr.io
34.136.8.83

Exit the instance's SSH session for now, we will SSH back to test address draining.

You can update existing Cloud NAT rules. For example, you can associate new IP addresses and drain existing IP addresses associated with existing rules.

Let's update the NAT Rules file as follows

From Cloud Shell:

export projectid=`gcloud config get-value project`

cat <<EOF >natrulesfile.txt
rules:
 - ruleNumber: 100
   match: destination.ip == '$producerip2'
   action:
     sourceNatDrainIps:
     -  /projects/$projectid/regions/us-east4/addresses/nat-address-2
     sourceNatActiveIps:
     -  /projects/$projectid/regions/us-east4/addresses/nat-address-3
EOF

What this new file does is now place "nat-address-2" in a drained state. And add "nat-address-3" in the active state. This should allow existing connections using nat-address-2 to terminate gracefully, while creating new connections only using nat-address-3.

Then let's update our existing NAT gateway using this rule file. From Cloud Shell:

gcloud alpha compute routers nats update consumer-nat-gw \
    --router=consumer-cr \
    --rules=natrulesfile.txt \
    --router-region=us-east4

You should expect the following output :

Updating nat [consumer-nat-gw] in router [consumer-cr]...done.

Validate that the rule has been successfully configured. From Cloud Shell:

gcloud alpha compute routers nats rules list \
--nat=consumer-nat-gw --router=consumer-cr \
--router-region=us-east4 --format=yaml

You should expect the following output :

---
action:
  sourceNatActiveIps:
  - https://www.googleapis.com/compute/alpha/projects/ghaleb-s2/regions/us-east4/addresses/nat-address-3
  sourceNatDrainIps:
  - https://www.googleapis.com/compute/alpha/projects/ghaleb-s2/regions/us-east4/addresses/nat-address-2
match: destination.ip == '35.192.142.134'
ruleNumber: 100

Notice how "nat-address-2" has now been placed into a drained state. We leave it up to you as an exercise to validate that new connections from the consumer VPC now use the correct NAT IPs.

Finally, to delete NAT rules from your Cloud NAT gateway and revert to the default behavior. You can use the following gcloud command. From Cloud Shell:

gcloud alpha compute routers nats rules delete 100 \
 --nat=consumer-nat-gw --router=consumer-cr \
 --router-region=us-east4 --quiet

You should expect the following output :

Updated [https://www.googleapis.com/compute/alpha/projects/ghaleb-s2/regions/us-east4/routers/consumer-cr]

To verify that no more NAT rules exist, let's use the NAT gateway describe command

gcloud alpha compute routers nats describe consumer-nat-gw \
 --router=consumer-cr --router-region=us-east4

You should expect the following output :

enableEndpointIndependentMapping: false
name: consumer-nat-gw
natIpAllocateOption: MANUAL_ONLY
natIps:
- https://www.googleapis.com/compute/alpha/projects/ghaleb-s2/regions/us-east4/addresses/nat-address-1
sourceSubnetworkIpRangesToNat: ALL_SUBNETWORKS_ALL_IP_RANGES

Notice how there isn't a "rules:" section in the output YAML. Indicating no NAT Rules configured.

To avoid recurring charges you should delete all resources associated with this codelab.

First delete all instances.

From Cloud Shell:

gcloud compute instances delete consumer-instance \
producer-instance-1 producer-instance-2 \
 --zone us-east4-a --quiet

Expected output :

Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/consumer-instance].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/producer-instance-1].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project Id>/zones/us-east4-a/instances/producer-instance-2].

Next, delete the Cloud Router. From Cloud Shell:

gcloud compute routers delete consumer-cr \
--region us-east4 --quiet

You should expect the following output :

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/routers/consumer-cr].

Release all external IP addresses. From Cloud Shell:

gcloud compute addresses delete nat-address-1 \
 nat-address-2 nat-address-3 producer-address-1 \
producer-address-2 --region us-east4 --quiet

You should expect the following output :

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-1].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-2].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/nat-address-3].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-1].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/addresses/producer-address-2].

Delete VPC firewall rules. From Cloud Shell:

gcloud compute firewall-rules delete consumer-allow-iap \
 producer-allow-8080 --quiet

You should expect the following output :

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/consumer-allow-iap].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/firewalls/producer-allow-8080].

Delete subnets. From Cloud Shell:

gcloud compute networks subnets delete consumer-e4 \
producer-e4 --region=us-east4 --quiet

You should expect the following output :

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/consumer-e4].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/us-east4/subnetworks/producer-e4].

Finally, let's delete the VPCs. From Cloud Shell:

gcloud compute networks delete consumer-vpc \
producer-vpc --quiet

You should expect the following output :

Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/consumer-vpc].
Deleted [https://www.googleapis.com/compute/v1/projects/<Project ID>/global/networks/producer-vpc].

You have completed the Cloud NAT Rules Lab!

What you covered

  • How to set up a Cloud NAT gateway in preparation for NAT Rules.
  • How to design NAT Rules using Common Expression Language (CEL).
  • How to create NAT Rules and attach them to a NAT Gateway.
  • How to test NAT Rules from an instance.
  • How to update a NAT Gateway's rules.
  • How to delete NAT rules and revert to the default Cloud NAT behavior.

Next Steps

  • Experiment with creating more complex NAT Rules such as this example
  • Explore draining NAT IP addresses and observe connection impact.
  • Learn more about Networking on Google Cloud Platform

©Google, Inc. or its affiliates. All rights reserved. Do not distribute.