The short answer
By default, EC2 instances, EMR clusters, and Glue workers running in private subnets without public IP addresses must communicate with S3 by routing traffic through a NAT Gateway. This introduces substantial hourly and per-gigabyte data transfer costs while exposing network routes outside the VPC.
Gateway Endpoints versus Interface Endpoints
AWS provides two distinct VPC endpoint types for connecting to Amazon S3:
- S3 Gateway Endpoint: Provided at zero additional cost. It works by injecting a route table entry into your VPC subnet route table, directing all traffic destined for S3 prefixes across the AWS private network backbone. It eliminates NAT Gateway transfer fees for all compute inside the VPC.
- S3 Interface Endpoint (PrivateLink): Provisions Elastic Network Interfaces (ENI) with private IP addresses inside your subnet. It incurs an hourly fee and per-gigabyte data processing fee, but supports access from on-premise networks over AWS Direct Connect or VPN connections.
Private Subnet (EMR / Glue / Lambda) | +---> S3 Gateway Endpoint (Free route table entry) ---> Amazon S3 Bucket | `---> Interface Endpoint (PrivateLink private IP) ---> Cross-Region / On-Prem
Restricting access with bucket policies
Using a Gateway Endpoint allows security teams to enforce strict network isolation. An S3 bucket policy can use the aws:sourceVpce condition key to explicitly deny any request that does not originate through your dedicated VPC endpoint, preventing data leakage over the public internet.