# AWS with Terraform Tutorial: AWS NAT Gateway (7)

> How to configure and use the Terraform aws_nat_gateway and aws_eip resources to create NAT Gateways and Elastic IPs for the private subnets of a VPC.

- Source: https://www.itwonderlab.com/aws-terraform-tutorial-aws-nat-gateway/
- Published: 2024-01-22
- Updated: 2026-10-05
- Author: Javier Ruiz Jiménez (https://www.javierruizjimenez.com/)
- Site: IT Wonder Lab (https://www.itwonderlab.com/)

---

## How to Create, and Manage AWS NAT Gateway with Terraform

**How to configure and use the Terraform `aws_nat_gateway` and `aws_eip` resource blocks to create and manage AWS NAT Gateway and its corresponding Public IPs inside each availability zone to enable Internet access from instances in private subnets.**

Welcome to our tutorial series where we dive into cloud infrastructure deployment using **[Terraform or OpenTofu on AWS](https://www.itwonderlab.com/tag/aws-terraform-essential-guide/)**. In this series, the fundamentals are shown, guiding you through the process of minimizing resource usage and simplifying the deployment complexities associated with cloud infrastructure.

This comprehensive **OpenTofu and Terraform tutorial** guides you step-by-step through creating infrastructure in AWS using Terraform.

![Terraform Basics, AWS Basics, Terraform AWS Provider, AWS VPC, AWS Subnets, AWS Internet Gateway, AWS NAT Gateway, AWS Routing Tables, AWS Security Groups, AWS Key Pairs, AWS AMIs, AWS EC2 Instances, AWS RDS, AWS Route 53 (DNS), AWS Auto Scaling, AWS Load Balancers, Terraform AWS & Ansible, Terraform Modules, Terraform Backends, Terraform Tools, Terraform CI/CD.](https://www.itwonderlab.com/media/tutorials/AWS-Terraform-Essentials/ITWL-Tutorials-AWS-Terraform-Essentials-Steps.svg)

Infrastructure as Code (IaC) helps maintain consistency, enables version control, enhances collaboration among teams, allows for easier replication of environments, streamlines the deployment and management of infrastructure boosting efficiency, and reducing errors in managing complex systems.

### Prerequisites

Read the previous sections of the tutorial, listed in the [series index](#series) at the end of this page.

### AWS NAT Gateway and EIP

![AWS NAT GW](https://www.itwonderlab.com/media/logos/Others/AWS_NAT_GW.svg)

An [AWS NAT Gateway](https://www.itwonderlab.com/aws-nat-gateway/) is a managed service that allows instances in a private [subnet](https://www.itwonderlab.com/aws-subnets/) to connect to the Internet while keeping them secure. It provides network address translation (NAT) for outbound traffic, allowing resources in a private subnet to access the internet while maintaining a private IP address.

AWS Instances in a private subnet only have private IPs. To access the Internet a NAT Gateway, located in a public subnet, is needed.

![Elastic IP Address](https://www.itwonderlab.com/media/logos/Others/AWS_EIP.svg)

The NAT Gateway maps the private IPs to an AWS EIP ([Elastic IP address](https://www.itwonderlab.com/aws-elastic-ip/)). Additionally, an Internet Gateway and proper routing tables are required.

To achieve redundancy each Availability Zone requires its own NAT Gateway.

![AWS NAT Gateway](https://www.itwonderlab.com/media/tutorials/AWS-Terraform-Essentials/ITWL-Tutorials-AWS-Terraform-Essentials-NAT.svg)

Terraform generates a **dependency graph** to understand the order in which resources should be created or modified. It helps determine the relationships and dependencies between different resources defined in your Terraform configuration. This ensures that resources are created or modified in the correct order to maintain a consistent infrastructure state. Sometimes Terraform or the provider can’t generate accurate dependency relations and require additional configuration using the `depends_on` Meta-Argument. For the NAT Gateway, a manual dependency on the Internet Gateway will be established.

### Terraform AWS Configuration Plan Definition

Previous sections of this [AWS with Terraform guide](https://www.itwonderlab.com/tag/aws-terraform-essential-guide/) have covered basic information about Terraform and AWS and have configured and used the AWS Terraform provider to create a VPC, four subnets, and an Internet Gateway.

It is time to create the **NAT Gateway**. Keep adding Terraform blocks to the `terraform-aws-tutorial.tf` created in previous sections.

### How to Create an AWS NAT Gateway and EIP with Terraform

Each Terraform `aws_nat_gateway` resource block creates a NAT Gateway and requires an existing `aws_eip` block that creates an Elastic IP (EIP) to use as a Public IP to access the Internet.

Elastic IPs are Public IPs associated with the AWS account. Once requested from AWS, the assigned IP doesn’t change (unless released and removed from the AWS Account). Having a fixed public IP is useful as it can be used outside AWS for firewall authorization or as a DNS Type A record.

NAT Gateway definition using Terraform, add the following blocks to the file `terraform-aws-tutorial.tf`:

```yaml
# NAT Gateway Public Availability Zone: A
resource "aws_nat_gateway" "ditwl-ngw-za-pub" {
  subnet_id = aws_subnet.ditwl-sn-za-pro-pub-00.id
  allocation_id = aws_eip.ditwl-eip-ngw-za.id

  tags = {
    Name = "ditwl-ngw-za-pub"
  }

  depends_on = [aws_internet_gateway.ditwl-ig]
}

# EIP for NAT Gateway in AZ A
resource "aws_eip" "ditwl-eip-ngw-za" {
  domain   = "vpc"

  tags = {
    Name = "ditwl-eip-ngw-za"
  }
}

# NAT Gateway Public Availability Zone: B
resource "aws_nat_gateway" "ditwl-ngw-zb-pub" {
  subnet_id = aws_subnet.ditwl-sn-zb-pro-pub-04.id
  allocation_id = aws_eip.ditwl-eip-ngw-zb.id

  tags = {
    Name = "ditwl-ngw-zb-pub"
  }

  depends_on = [aws_internet_gateway.ditwl-ig]
}

# EIP for NAT Gateway in AZ B
resource "aws_eip" "ditwl-eip-ngw-zb" {
  domain   = "vpc"

  tags = {
    Name = "ditwl-eip-ngw-zb"
  }  
}
```

#### NAT Gateway Public Availability Zone A

Named `ditwl-ngw-za-pub`, is created inside the subnet `ditwl-sn-za-pro-pub-00` created in the previous tutorial, using its Terraform reference `aws_subnet.ditwl-sn-za-pro-pub-00.id`

A dependency is added specifying that this NAT Gateway depends on the existence of the Internet Gateway, created in the previous tutorial and identified with its Terraform name `aws_internet_gateway.ditwl-ig`.

The EIP is defined right after the NAT although Terraform will create the EIP before attempting to create the NAT Gateway as it is an explicit dependency (a parameter to the NAT Gateway block).

This `aws_nat_gateway` will be used as **a target** in the routing table for private subnets in **availability zone A** using its Terraform type and name: `aws_nat_gateway.ditwl-ngw-za-pub`.

#### NAT Gateway Public Availability Zone B

Named `ditwl-ngw-zb-pub`, is created inside the subnet `ditwl-sn-zb-pro-pub-04` created in the previous tutorial, using its Terraform reference `aws_subnet.ditwl-sn-zb-pro-pub-04.id`

A dependency is added specifying that this NAT Gateway depends on the existence of the Internet Gateway, created in the previous tutorial and identified with its Terraform name `aws_internet_gateway.ditwl-ig`.

This `aws_nat_gateway` will be used as **a target** in the routing table for private subnets in **availability zone B** using its Terraform type and name: `aws_nat_gateway.ditwl-ngw-zb-pub`.

### Run the Terraform Plan

Open a command line shell in the directory where the file `terraform-aws-tutorial.tf` is located, and run the Terraform or OpenTofu `plan` and `apply` commands.

#### Plan using OpenTofu

Run `tofu plan` to generate and review the execution plan. Check each line and value to make sure that it corresponds to the desired change.

The VPC, Subnets, and the Internet Gateway were already created in the previous Terraform execution so now only the new NAT Gateways will be created. Terraform or OpenTofu show `Refreshing state` for each of the existing elements and the planned actions for the changes.

```shell
$ tofu plan
aws_vpc.ditlw-vpc: Refreshing state... [id=vpc-0bed1f6c715e9a909]
aws_internet_gateway.ditwl-ig: Refreshing state... [id=igw-033b206763b59357e]
aws_subnet.ditwl-sn-za-pro-pub-00: Refreshing state... [id=subnet-07753bf540026684d]
aws_subnet.ditwl-sn-za-pro-pri-02: Refreshing state... [id=subnet-096bf79e4bab2e1c4]
aws_subnet.ditwl-sn-zb-pro-pri-06: Refreshing state... [id=subnet-0f5662bd40a070e55]
aws_subnet.ditwl-sn-zb-pro-pub-04: Refreshing state... [id=subnet-0d34cee7300e9fa45]

OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

OpenTofu will perform the following actions:

  # aws_eip.ditwl-eip-ngw-za will be created
  + resource "aws_eip" "ditwl-eip-ngw-za" {
      + domain               = "vpc"
      ...
      + public_ip            = (known after apply)
      + tags                 = {
          + "Name" = "ditwl-eip-ngw-za"
        }
      + tags_all             = {
          + "Name"        = "ditwl-eip-ngw-za"
          + "cost_center" = "marketing-department"
          + "environment" = "pro"
          + "owner"       = "IT Wonder Lab"
        }
      + vpc                  = (known after apply)
    }

  # aws_eip.ditwl-eip-ngw-zb will be created
  + resource "aws_eip" "ditwl-eip-ngw-zb" {
      + domain               = "vpc"
      ...
      + public_ip            = (known after apply)
      + tags                 = {
          + "Name" = "ditwl-eip-ngw-zb"
        }
      + tags_all             = {
          + "Name"        = "ditwl-eip-ngw-zb"
          + "cost_center" = "marketing-department"
          + "environment" = "pro"
          + "owner"       = "IT Wonder Lab"
        }
      + vpc                  = (known after apply)
    }

  # aws_nat_gateway.ditwl-ngw-za-pub will be created
  + resource "aws_nat_gateway" "ditwl-ngw-za-pub" {
      + allocation_id                      = (known after apply)
      + association_id                     = (known after apply)
      + connectivity_type                  = "public"
      ...
      + subnet_id                          = "subnet-07753bf540026684d"
      + tags                               = {
          + "Name" = "ditwl-ngw-za-pub"
        }
      + tags_all                           = {
          + "Name"        = "ditwl-ngw-za-pub"
          + "cost_center" = "marketing-department"
          + "environment" = "pro"
          + "owner"       = "IT Wonder Lab"
        }
    }

  # aws_nat_gateway.ditwl-ngw-zb-pub will be created
  + resource "aws_nat_gateway" "ditwl-ngw-zb-pub" {
      + allocation_id                      = (known after apply)
      + association_id                     = (known after apply)
      + connectivity_type                  = "public"
      ...
      + subnet_id                          = "subnet-0d34cee7300e9fa45"
      + tags                               = {
          + "Name" = "ditwl-ngw-zb-pub"
        }
      + tags_all                           = {
          + "Name"        = "ditwl-ngw-zb-pub"
          + "cost_center" = "marketing-department"
          + "environment" = "pro"
          + "owner"       = "IT Wonder Lab"
        }
    }

Plan: 4 to add, 0 to change, 0 to destroy.
```

#### Apply the changes using OpenTofu

Run `tofu apply` to generate and **apply** the execution plan. OpenTofu will generate a new plan and ask for confirmation before applying the changes. Review again the changes and answer yes or no to apply the changes in AWS.

```shell
$ tofu apply
aws_vpc.ditlw-vpc: Refreshing state... [id=vpc-0bed1f6c715e9a909]
aws_internet_gateway.ditwl-ig: Refreshing state... [id=igw-033b206763b59357e]
aws_subnet.ditwl-sn-za-pro-pri-02: Refreshing state... [id=subnet-096bf79e4bab2e1c4]
aws_subnet.ditwl-sn-za-pro-pub-00: Refreshing state... [id=subnet-07753bf540026684d]
aws_subnet.ditwl-sn-zb-pro-pub-04: Refreshing state... [id=subnet-0d34cee7300e9fa45]
aws_subnet.ditwl-sn-zb-pro-pri-06: Refreshing state... [id=subnet-0f5662bd40a070e55]

OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

OpenTofu will perform the following actions:

  # aws_eip.ditwl-eip-ngw-za will be created
  + resource "aws_eip" "ditwl-eip-ngw-za" {
    ...
    }

  # aws_eip.ditwl-eip-ngw-zb will be created
  + resource "aws_eip" "ditwl-eip-ngw-zb" {
    ...
    }

  # aws_nat_gateway.ditwl-ngw-za-pub will be created
  + resource "aws_nat_gateway" "ditwl-ngw-za-pub" {
    ...
    }

  # aws_nat_gateway.ditwl-ngw-zb-pub will be created
  + resource "aws_nat_gateway" "ditwl-ngw-zb-pub" {
    ...
    }

Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  OpenTofu will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_eip.ditwl-eip-ngw-za: Creating...
aws_eip.ditwl-eip-ngw-zb: Creating...
aws_eip.ditwl-eip-ngw-za: Creation complete after 2s [id=eipalloc-09d067ed40aa0a4b0]
aws_nat_gateway.ditwl-ngw-za-pub: Creating...
aws_eip.ditwl-eip-ngw-zb: Creation complete after 2s [id=eipalloc-01af98f4b5057cc20]
aws_nat_gateway.ditwl-ngw-zb-pub: Creating...
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [10s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [10s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [20s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [20s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [30s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [30s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [40s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [40s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [50s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [50s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [1m0s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [1m0s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [1m10s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [1m10s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [1m20s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [1m20s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still creating... [1m30s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [1m30s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Creation complete after 1m39s [id=nat-0d7980bc4c9f1623f]
aws_nat_gateway.ditwl-ngw-zb-pub: Still creating... [1m40s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Creation complete after 1m50s [id=nat-05b3376011cb51399]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed
```

Review the result, it should be `4 (resource) added, 0 changed, 0 destroyed`.

Check using the AWS web Console that the NAT Gateways and the EIPs have been created:

-   Navigate to [AWS Console: VPC – NAT gateways](https://us-east-1.console.aws.amazon.com/vpcconsole/home?region=us-east-1#NatGateways:):

![NatGateways VPC Console](https://www.itwonderlab.com/media/tutorials/AWS-Terraform-Essentials/NatGateways-VPC-Console.png)

If you don’t see the NAT gateway check on the right top corner that the Region is N. Virginia that corresponds to us-east-1.

Click on the Public IPs to navigate to the EIP console and see its properties.

### NAT Gateways and EIP Cost

NAT gateways are specialized instances that have a running cost, AWS charges for each “NAT Gateway-hour” that each gateway is provisioned and available, additionally, each GB of data processed is charged separately.

Since February 1, 2024, AWS also charges hourly for every public IPv4 address, including the EIPs, whether they are in use or not. See [AWS NAT Gateway](https://www.itwonderlab.com/aws-nat-gateway/) and [AWS Elastic IP](https://www.itwonderlab.com/aws-elastic-ip/).

### Destroying AWS Infrastructure with Terraform

In Terraform, anything following the # on a line is treated as a comment and is ignored by Terraform during execution.

When a resource block is removed or commented from a Terraform configuration file, in the next execution Terraform will destroy the element in the Cloud.

Take this opportunity to comment out the Terraform blocks inside the `terraform-aws-tutorial.tf` file that creates the NAT Gateways and the EIPs. Add a # on each line to comment out the 4 blocks or use a block comment /\*

``` title="Line Comment"
# # NAT Gateway Public Availability Zone: A
# resource "aws_nat_gateway" "ditwl-ngw-za-pub" {
#   subnet_id = aws_subnet.ditwl-sn-za-pro-pub-00.id
#   allocation_id = aws_eip.ditwl-eip-ngw-za.id

#   tags = {
#     Name = "ditwl-ngw-za-pub"
#   }

#   depends_on = [aws_internet_gateway.ditwl-ig]
# }

# # EIP for NAT Gateway in AZ A
# resource "aws_eip" "ditwl-eip-ngw-za" {
#   domain   = "vpc"

#   tags = {
#     Name = "ditwl-eip-ngw-za"
#   }
# }

# # NAT Gateway Public Availability Zone: B
# resource "aws_nat_gateway" "ditwl-ngw-zb-pub" {
...
```

```hcl title="Block Comment"
/*
# NAT Gateway Public Availability Zone: A
resource "aws_nat_gateway" "ditwl-ngw-za-pub" {
  subnet_id = aws_subnet.ditwl-sn-za-pro-pub-00.id
  allocation_id = aws_eip.ditwl-eip-ngw-za.id

  tags = {
    Name = "ditwl-ngw-za-pub"
  }

  depends_on = [aws_internet_gateway.ditwl-ig]
}

...

# EIP for NAT Gateway in AZ B
resource "aws_eip" "ditwl-eip-ngw-zb" {
  domain   = "vpc"

  tags = {
    Name = "ditwl-eip-ngw-zb"
  }  
}
*/
```

Now, apply the changes in the Cloud by running `tofu apply` to generate and apply the execution plan:

```shell
$ tofu apply
aws_nat_gateway.ditwl-ngw-zb-pub: Refreshing state... [id=nat-05b3376011cb51399]
aws_nat_gateway.ditwl-ngw-za-pub: Refreshing state... [id=nat-0d7980bc4c9f1623f]
aws_eip.ditwl-eip-ngw-zb: Refreshing state... [id=eipalloc-01af98f4b5057cc20]
aws_eip.ditwl-eip-ngw-za: Refreshing state... [id=eipalloc-09d067ed40aa0a4b0]
aws_vpc.ditlw-vpc: Refreshing state... [id=vpc-0bed1f6c715e9a909]
aws_internet_gateway.ditwl-ig: Refreshing state... [id=igw-033b206763b59357e]
aws_subnet.ditwl-sn-za-pro-pub-00: Refreshing state... [id=subnet-07753bf540026684d]
aws_subnet.ditwl-sn-za-pro-pri-02: Refreshing state... [id=subnet-096bf79e4bab2e1c4]
aws_subnet.ditwl-sn-zb-pro-pri-06: Refreshing state... [id=subnet-0f5662bd40a070e55]
aws_subnet.ditwl-sn-zb-pro-pub-04: Refreshing state... [id=subnet-0d34cee7300e9fa45]

OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  - destroy

OpenTofu will perform the following actions:

  # aws_eip.ditwl-eip-ngw-za will be destroyed
  # (because aws_eip.ditwl-eip-ngw-za is not in configuration)
  - resource "aws_eip" "ditwl-eip-ngw-za" {
      - allocation_id        = "eipalloc-09d067ed40aa0a4b0" -> null
      - association_id       = "eipassoc-0a73a6aa8c1a3e887" -> null
      - domain               = "vpc" -> null
      - id                   = "eipalloc-09d067ed40aa0a4b0" -> null
      - network_border_group = "us-east-1" -> null
      - network_interface    = "eni-0fc6a8a09b59458e5" -> null
      - private_dns          = "ip-172-21-0-190.ec2.internal" -> null
      - private_ip           = "172.21.0.190" -> null
      - public_dns           = "ec2-3-232-192-205.compute-1.amazonaws.com" -> null
      - public_ip            = "3.232.192.205" -> null
      - public_ipv4_pool     = "amazon" -> null
      - tags                 = {
          - "Name" = "ditwl-eip-ngw-za"
        } -> null
      - tags_all             = {
          - "Name"        = "ditwl-eip-ngw-za"
          - "cost_center" = "marketing-department"
          - "environment" = "pro"
          - "owner"       = "IT Wonder Lab"
        } -> null
      - vpc                  = true -> null
    }

  # aws_eip.ditwl-eip-ngw-zb will be destroyed
  # (because aws_eip.ditwl-eip-ngw-zb is not in configuration)
  - resource "aws_eip" "ditwl-eip-ngw-zb" {
      - allocation_id        = "eipalloc-01af98f4b5057cc20" -> null
      - association_id       = "eipassoc-0771a263deb9c67ad" -> null
      - domain               = "vpc" -> null
      - id                   = "eipalloc-01af98f4b5057cc20" -> null
      - network_border_group = "us-east-1" -> null
      - network_interface    = "eni-08c2f941edd62d0cb" -> null
      - private_dns          = "ip-172-21-5-164.ec2.internal" -> null
      - private_ip           = "172.21.5.164" -> null
      - public_dns           = "ec2-107-21-204-41.compute-1.amazonaws.com" -> null
      - public_ip            = "107.21.204.41" -> null
      - public_ipv4_pool     = "amazon" -> null
      - tags                 = {
          - "Name" = "ditwl-eip-ngw-zb"
        } -> null
      - tags_all             = {
          - "Name"        = "ditwl-eip-ngw-zb"
          - "cost_center" = "marketing-department"
          - "environment" = "pro"
          - "owner"       = "IT Wonder Lab"
        } -> null
      - vpc                  = true -> null
    }

  # aws_nat_gateway.ditwl-ngw-za-pub will be destroyed
  # (because aws_nat_gateway.ditwl-ngw-za-pub is not in configuration)
  - resource "aws_nat_gateway" "ditwl-ngw-za-pub" {
      - allocation_id                      = "eipalloc-09d067ed40aa0a4b0" -> null
      - association_id                     = "eipassoc-0a73a6aa8c1a3e887" -> null
      - connectivity_type                  = "public" -> null
      - id                                 = "nat-0d7980bc4c9f1623f" -> null
      - network_interface_id               = "eni-0fc6a8a09b59458e5" -> null
      - private_ip                         = "172.21.0.190" -> null
      - public_ip                          = "3.232.192.205" -> null
      - secondary_allocation_ids           = [] -> null
      - secondary_private_ip_address_count = 0 -> null
      - secondary_private_ip_addresses     = [] -> null
      - subnet_id                          = "subnet-07753bf540026684d" -> null
      - tags                               = {
          - "Name" = "ditwl-ngw-za-pub"
        } -> null
      - tags_all                           = {
          - "Name"        = "ditwl-ngw-za-pub"
          - "cost_center" = "marketing-department"
          - "environment" = "pro"
          - "owner"       = "IT Wonder Lab"
        } -> null
    }

  # aws_nat_gateway.ditwl-ngw-zb-pub will be destroyed
  # (because aws_nat_gateway.ditwl-ngw-zb-pub is not in configuration)
  - resource "aws_nat_gateway" "ditwl-ngw-zb-pub" {
      - allocation_id                      = "eipalloc-01af98f4b5057cc20" -> null
      - association_id                     = "eipassoc-0771a263deb9c67ad" -> null
      - connectivity_type                  = "public" -> null
      - id                                 = "nat-05b3376011cb51399" -> null
      - network_interface_id               = "eni-08c2f941edd62d0cb" -> null
      - private_ip                         = "172.21.5.164" -> null
      - public_ip                          = "107.21.204.41" -> null
      - secondary_allocation_ids           = [] -> null
      - secondary_private_ip_address_count = 0 -> null
      - secondary_private_ip_addresses     = [] -> null
      - subnet_id                          = "subnet-0d34cee7300e9fa45" -> null
      - tags                               = {
          - "Name" = "ditwl-ngw-zb-pub"
        } -> null
      - tags_all                           = {
          - "Name"        = "ditwl-ngw-zb-pub"
          - "cost_center" = "marketing-department"
          - "environment" = "pro"
          - "owner"       = "IT Wonder Lab"
        } -> null
    }

Plan: 0 to add, 0 to change, 4 to destroy.

Do you want to perform these actions?
  OpenTofu will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_nat_gateway.ditwl-ngw-za-pub: Destroying... [id=nat-0d7980bc4c9f1623f]
aws_nat_gateway.ditwl-ngw-zb-pub: Destroying... [id=nat-05b3376011cb51399]
aws_nat_gateway.ditwl-ngw-zb-pub: Still destroying... [id=nat-05b3376011cb51399, 10s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still destroying... [id=nat-0d7980bc4c9f1623f, 10s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still destroying... [id=nat-05b3376011cb51399, 20s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still destroying... [id=nat-0d7980bc4c9f1623f, 20s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still destroying... [id=nat-05b3376011cb51399, 30s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still destroying... [id=nat-0d7980bc4c9f1623f, 30s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still destroying... [id=nat-0d7980bc4c9f1623f, 40s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Still destroying... [id=nat-05b3376011cb51399, 40s elapsed]
aws_nat_gateway.ditwl-ngw-zb-pub: Destruction complete after 44s
aws_eip.ditwl-eip-ngw-zb: Destroying... [id=eipalloc-01af98f4b5057cc20]
aws_eip.ditwl-eip-ngw-zb: Destruction complete after 2s
aws_nat_gateway.ditwl-ngw-za-pub: Still destroying... [id=nat-0d7980bc4c9f1623f, 50s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Still destroying... [id=nat-0d7980bc4c9f1623f, 1m0s elapsed]
aws_nat_gateway.ditwl-ngw-za-pub: Destruction complete after 1m6s
aws_eip.ditwl-eip-ngw-za: Destroying... [id=eipalloc-09d067ed40aa0a4b0]
aws_eip.ditwl-eip-ngw-za: Destruction complete after 5s

Apply complete! Resources: 0 added, 0 changed, 4 destroyed.
```

Review the result, it should be `0 (resource) added, 0 changed, 4 destroyed`. Terraform has destroyed the two EIPs and the NAT Gateways because the cloud resources were not present in the configuration. AWS stops charging resource usage or availability once the resource is destroyed.

### Common Questions About AWS NAT Gateways

#### When to use a NAT Gateway?

When resources in a private subnet need to access the internet for tasks such as downloading software updates, fetching data from external APIs, or accessing external services.

In a multi-tier architecture with public and private subnets, the private subnet might need to access the Internet while still being protected from direct incoming traffic, the NAT Gateway acts as a barrier between the private instances and the public Internet, enhancing security by avoiding direct exposure of private instances.

Applications that initiate outbound connections and require consistent source IP addresses for tasks such as accessing third-party APIs or external services. The NAT Gateway uses a static Elastic IP address, having a fixed source IP allows firewall and access control authorization.

NAT is also useful when compliance standards mandate secure handling of outbound Internet traffic.

#### How is NAT Gateway different from NAT instance?

NAT Gateway is a managed service, offering higher availability and scalability compared to a manually configured NAT instance.

#### Can I resize an AWS NAT Gateway?

No, AWS NAT Gateway sizes are fixed. A NAT gateway supports 5 Gbps of bandwidth and automatically scales up to 100 Gbps and can process one million packets per second and automatically scales up to ten million packets per second. If your user case requires more bandwidth, split your resources into multiple subnets and create multiple NAT Gateways. Each IPv4 address can support up to 55,000 simultaneous connections to each unique destination. Check the [NAT gateway quotas](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-basics.html) for the current limits.

#### Why deploy NAT Gateways across multiple Availability Zones?

It provides high availability. If one Availability Zone experiences issues, the others can still handle outbound traffic.

#### What security measures should be taken with NAT Gateway?

Configure security groups to allow only necessary outbound traffic and update route tables in private subnets to direct traffic to the NAT Gateway.

#### How to monitor AWS NAT Gateway?

Monitor with [AWS CloudWatch](https://www.itwonderlab.com/aws-cloudwatch/): the NAT Gateway publishes metrics such as bytes in and out, active connections and port allocation errors. Enable VPC Flow Logs for activity tracking and troubleshooting.

### Next Steps

Continue with [AWS Routing Tables](https://www.itwonderlab.com/aws-terraform-tutorial-aws-routing-tables/), or see the [full series index](#series).
