Mohamed ARKID logo

Command Palette

Search for a command to run...

Command Palette

Search for a command to run...

Blog

Eliminate AWS NAT Gateway Overcharges: Terraform Guide

VPC NAT Gateway processing fees can double your AWS bill. Learn to route traffic securely using VPC Endpoints with copy-pasteable Terraform code.

Updated 5 min read

TL;DR

If you are transfering gigabytes of data between your private compute nodes and AWS services like ECR, S3, or DynamoDB, you are likely paying a massive premium on NAT Gateway Data Processing charges ($0.045 per GB).

  • The Solution: Replace public NAT Gateway paths with private VPC Endpoints (AWS PrivateLink).
  • The Savings: Eliminates the $0.045/GB data processing tax entirely for in-network traffic, regularly slashing overall NAT Gateway spend by 70% to 90%.
  • The Code: Drop-in Terraform modules for Gateway Endpoints (free) and Interface Endpoints are detailed below.

Is your AWS bill out of control? I will personally review your AWS architecture, locate where the data transfer charges are leaking, and write the Terraform modules to fix it.

Book a Free 15-Minute AWS Bill Review — let's find the waste and cut your bill starting today.


The Silent Killer: Data Processing Fees

When you configure a public NAT Gateway in AWS, you pay two different charges:

  1. The Hourly Charge: $0.045 per hour per NAT Gateway ($32/month).
  2. The Data Processing Charge: $0.045 per GB for all data passing through.

The hourly charge is negligible. The data processing charge is a financial landmine.

If your private EC2 instances or EKS pods pull a 2 GB Docker image from ECR, read 500 GB of backups from S3, or query a DynamoDB table, and that traffic goes through your NAT Gateway, you are paying $0.045/GB to route data that never leaves the AWS global network.

At 10 TB of monthly data transfer, you are burning $450/month on NAT Gateway tax. At 100 TB, that tax jumps to $4,500/month.

The Fix: VPC Endpoints

Instead of routing traffic to AWS services over the public internet through a NAT Gateway, you can create VPC Endpoints. This exposes a private IP address inside your VPC subnet that connects directly to the target AWS service using the private AWS fiber network.

AWS offers two types of VPC Endpoints:

1. Gateway Endpoints (Free)

Available only for S3 and DynamoDB. They modify your subnet route tables to direct traffic privately.

  • Cost: 100% Free.
  • Data Processing Fee: $0.00.

2. Interface Endpoints (Paid)

Available for almost all other AWS services (ECR, KMS, Systems Manager, CloudWatch, API Gateway). They create an Elastic Network Interface (ENI) with a private IP in your subnets.

  • Cost: $0.01 per hour per availability zone ($7.20/month per AZ).
  • Data Processing Fee: ~$0.01 per GB (a 78% reduction compared to NAT Gateway's $0.045/GB).

Implementing with Terraform

Let's deploy these endpoints using Terraform to automate the cost optimization safely.

Step 1: Deploy Free S3 and DynamoDB Gateway Endpoints

Since Gateway Endpoints are completely free and have no data processing charges, there is absolutely zero reason not to deploy them today.

vpc-gateway-endpoints.tf

# Retrieve the current VPC details
data "aws_vpc" "selected" {
  id = var.vpc_id
}
 
# Retrieve all private route table IDs where you want private routing
data "aws_route_table" "private" {
  count     = length(var.private_subnet_ids)
  subnet_id = var.private_subnet_ids[count.index]
}
 
locals {
  route_table_ids = distinct([for rt in data.aws_route_table.private : rt.id])
}
 
# Create S3 Gateway Endpoint
resource "aws_vpc_endpoint" "s3" {
  vpc_id            = data.aws_vpc.selected.id
  service_name      = "com.amazonaws.${var.aws_region}.s3"
  vpc_endpoint_type = "Gateway"
  route_table_ids   = local.route_table_ids
 
  tags = {
    Name        = "s3-gateway-endpoint"
    Environment = var.environment
    ManagedBy   = "Terraform"
  }
}
 
# Create DynamoDB Gateway Endpoint
resource "aws_vpc_endpoint" "dynamodb" {
  vpc_id            = data.aws_vpc.selected.id
  service_name      = "com.amazonaws.${var.aws_region}.dynamodb"
  vpc_endpoint_type = "Gateway"
  route_table_ids   = local.route_table_ids
 
  tags = {
    Name        = "dynamodb-gateway-endpoint"
    Environment = var.environment
    ManagedBy   = "Terraform"
  }
}

Step 2: Deploy ECR and CloudWatch Interface Endpoints

If you run EKS, ECR image pulls are typically your largest source of NAT Gateway processing fees. Routing ECR and CloudWatch traffic through private Interface Endpoints bypasses the NAT Gateway entirely.

vpc-interface-endpoints.tf

# Security Group to allow internal HTTPS traffic to the Endpoints
resource "aws_security_group" "vpc_endpoints" {
  name        = "${var.environment}-vpc-endpoints-sg"
  description = "Allow private traffic to VPC endpoints"
  vpc_id      = data.aws_vpc.selected.id
 
  ingress {
    description = "Allow HTTPS from within the VPC"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = [data.aws_vpc.selected.cidr_block]
  }
 
  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }
 
  tags = {
    Name        = "vpc-endpoints-sg"
    Environment = var.environment
  }
}
 
# ECR API Endpoint (for image lists and registry calls)
resource "aws_vpc_endpoint" "ecr_api" {
  vpc_id              = data.aws_vpc.selected.id
  service_name        = "com.amazonaws.${var.aws_region}.ecr.api"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = var.private_subnet_ids
  security_group_ids  = [aws_security_group.vpc_endpoints.id]
  private_dns_enabled = true
 
  tags = {
    Name        = "ecr-api-endpoint"
    Environment = var.environment
  }
}
 
# ECR DKR Endpoint (for actual image layer pulls)
resource "aws_vpc_endpoint" "ecr_dkr" {
  vpc_id              = data.aws_vpc.selected.id
  service_name        = "com.amazonaws.${var.aws_region}.ecr.dkr"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = var.private_subnet_ids
  security_group_ids  = [aws_security_group.vpc_endpoints.id]
  private_dns_enabled = true
 
  tags = {
    Name        = "ecr-dkr-endpoint"
    Environment = var.environment
  }
}

Free Lead Magnet

AWS Cost Reduction: The 10-Point FinOps Checklist

Get the exact step-by-step audit playbook I use to slash AWS bills by 30% in under 2 hours. Zero fluff, just production-tested commands and configurations.

I respect your privacy. No spam, unsubscribe anytime.


When Are Interface Endpoints NOT Worth It?

Interface Endpoints cost ~$7.20/month per availability zone. If you deploy an endpoint across 3 AZs, you are paying $21.60/month flat, plus $0.01/GB.

If a specific service (like KMS or Secret Manager) only processes 5 GB of traffic a month inside your VPC:

  • Through NAT Gateway: $0.22 in data processing.
  • Through VPC Endpoint: $21.60 in flat hourly fees + $0.05 in processing.

In this scenario, deploying the Interface Endpoint is actually more expensive than routing it through the NAT Gateway.

Rule of thumb: Only deploy Interface Endpoints for services where your monthly data volume exceeds 300 GB per endpoint. For low-volume services, route them through the public NAT Gateway.

The Payoff

By routing S3/DynamoDB traffic to Gateway Endpoints (free) and high-volume container registry/logging traffic to Interface Endpoints, you decouple your cloud billing from your data transfer volume.

Instead of your AWS bill scaling linearly with your analytics processing or EKS deployments, your NAT Gateway fees drop to a predictable baseline.

This single optimization pays for itself in the first hour of EKS auto-scaling.


Unsure if VPC Endpoints will actually save you money? I will analyze your data transfer logs and calculate the exact return-on-investment before writing a single line of Terraform.

Stop overpaying for internal network traffic. Book a Free AWS Cost Audit.

Free Architecture Offer

Get a Free 15-Minute AWS Bill Review

Stop overpaying Amazon. I will review your AWS infrastructure, locate the exact resources causing cloud waste, and hand you a prioritized roadmap to cut your bill by 30%. No sales fluff—just engineering fixes.

✓ 15-Minute Quick Call✓ Direct Tech Analysis✓ Zero Commitments
Mohamed ARKID
Mohamed ARKID

DevOps Consultant & Cloud Engineer

I build systems that run reliably, scale efficiently, and deploy intelligently. See how I can help your team.