NAT gateways in the available state that may be processing S3 traffic
What does ZopNight detect here?
ZopNight keeps this NAT gateway S3 check switched off and raises no finding. Pricing the move to an S3 gateway endpoint needs the S3 share of NAT traffic, and CloudWatch reports only total bytes per gateway. Until that split is measurable, the honest output is silence; use VPC Flow Logs and the `route.nat-gateway-id` route filter to check your own gateways.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1510 |
| Category | advisory |
| Severity | low |
| Metric | none — pure configuration read |
| Source | ZopNight |
| Permissions used | ec2:DescribeNatGateways · ec2:DescribeRouteTables · ec2:DescribeVpcEndpoints |
Where it applies
What this check was meant to catch
Workloads in private subnets often reach Amazon S3 through a NAT gateway simply because that is the default route to anything outside the VPC. Each of those bytes incurs the NAT gateway’s data processing charge. The VPC pricing example walks through a 1 GB upload from an instance to S3 in the same Region: the transfer itself is free, yet the NAT gateway still charges $0.045 for processing it, and AWS notes that a gateway VPC endpoint would have avoided that charge.
Current status: no finding is emitted
ZopNight has switched this check off for every NAT gateway. The earlier version produced an advisory with no dollar figure attached, which did not meet ZopNight’s standard that a cost finding either carries a concrete number or is not shown. The number needed is the S3 share of the gateway’s traffic, and neither the NAT gateway’s CloudWatch metrics nor ZopNight’s inventory expose it. A sibling page, NAT Gateway High Outbound Traffic, Consider a Gateway Endpoint, explains the same gap for S3 and DynamoDB together and shows how to measure the split with Flow Logs.
Tracing which subnets use a NAT gateway
Start from the gateway and work back to the subnets whose default route points at it:
aws ec2 describe-route-tables \ --filters Name=route.nat-gateway-id,Values=nat-0123456789abcdef0 \ --query 'RouteTables[].[RouteTableId,VpcId,Associations[].SubnetId]'Then check whether those same route tables already have a route to the S3 prefix list, which is what a gateway endpoint adds:
aws ec2 describe-route-tables \ --filters Name=route.nat-gateway-id,Values=nat-0123456789abcdef0 \ --query 'RouteTables[].Routes[?DestinationPrefixListId!=`null`].[DestinationPrefixListId,GatewayId]'No prefix-list route means S3 traffic from those subnets is going through the NAT gateway.
What decides whether the change is worth it
The saving scales with S3 volume. A subnet that moves a few gigabytes a month saves cents; a data pipeline reading terabytes from S3 saves real money. Gateway endpoints carry no additional charge, so there is no break-even point, only a question of whether the change is worth an engineer’s time.
monthly saving = S3-bound GB through the NAT gateway per month x NAT processing rate per GBMoving S3 traffic to a gateway endpoint
- Create an S3 gateway endpoint in the VPC:
aws ec2 create-vpc-endpoint --vpc-id vpc-0abc --service-name com.amazonaws.us-east-1.s3 --route-table-ids rtb-0abc. - Review bucket policies that allow access only from the NAT gateway’s public IP. Requests through
the endpoint arrive from private addresses, so restrict by endpoint with
aws:sourceVpceinstead. - Confirm the new prefix-list route appears in each private route table.