Sometimes I feel that AWS is the master of unexpected costs. I was recently surprised by the cost of the NAT gateway - $0.045 per GB?! on top of $0.045/h? Obviously you’ll need it if you want instances on private subnets to access the Internet. For network-intensive applications such as web crawlers, a NAT gateway can be more expensive than instances. Fortunately, there is a simple way to reduce the cost - enable IPv6 and use an Egress-only Internet gateway.
Egress-only Internet Gateway vs NAT Gateway
NAT Gateway allows instances on private subnets to access the Internet over IPv4. Located on a public subnet, it connects instances to the Internet Gateway.
Source - https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat.html
Egress-only Internet Gateway allows instances on private subnets to access the Internet directly via IPv6. Basically, you cut out the middleman, which isn’t necessary because IPv6 doesn’t require address translation. What is important, your instances will still be inaccessible from the outside world. And here’s the best part - it’s free!
Source - https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway.html
Unfortunately, not all of the Internet is available on IPv6, so it’s not a silver bullet. We’ll keep NAT Gateways for IPv4 traffic. This is what our final architecture will look like:
Source - https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-example.html
Enabling Egress-only Internet Gateway
As you might guess, we need to enable IPv6 first. This can be very easy if you are using the AWS CDK. If you are doing a manual setup, you may need to go through some additional steps - see https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-add.html
Note that you may need to update other parts of your infrastructure to support IPv6.
For example, if you’re using ECS, IPv6 will not work with the bridge
network mode.
Also remember to update your security groups to prevent them from blocking outgoing traffic over IPv6.
With IPv6 enabled, you can create an Egress-only Internet Gateway. AWS CDK created it automatically for me, but you can also create it manually - https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway-working-with.html
The easiest way to check if traffic is going over IPv6 is to check the NAT Gateway metrics in Cloudwatch.
You should see a significant drop in metrics such as BytesOutToDestination
or BytesInFromDestination
.
You may want to tweak your application to prioritize IPv6 traffic. I can’t help you with that. In my case, I had to override DNS resolution to prioritize IPv6 over IPv4 for my HTTP client.
Other ways to reduce NAT Gateway cost
There are a few other tips to reduce NAT gateway costs. I won’t cover them in detail.
- Use Gateway Endpoints / Interface Endpoints for AWS services - https://docs.aws.amazon.com/vpc/latest/privatelink/gateway-endpoints.html
- Launch your own NAT instance instead. It can be cheaper, but it requires more management overhead - https://docs.aws.amazon.com/vpc/latest/userguide/work-with-nat-instances.html
Summary
If you are looking for a quick way to reduce the cost of NAT Gateway, enabling IPv6 and Egress-only Internet Gateway is an easy way to do it. It’s not a silver bullet, but hopefully it will save you some money.