Definition
- VPC Endpoint – A VPC component that lets resources reach supported services privately, without an IGW, NAT Gateway, or public IPs.
- Gateway Endpoint – A route-table target for S3 and DynamoDB only, free of charge, that keeps traffic on the AWS network.
- Interface Endpoint – An elastic network interface (ENI) with a private IP in your subnet, powered by PrivateLink, used for most other services.
- AWS PrivateLink – The technology that exposes a service through a private IP in the consumer's VPC, connecting only that service rather than whole networks.
- Endpoint Policy – A JSON policy that restricts which resources the endpoint can access, providing data-exfiltration control.
Normally, to reach a service outside your building you send a courier out onto the public street. A VPC Endpoint builds a private internal corridor straight to that service so the courier never steps outside. A Gateway Endpoint is a free corridor reserved for the S3 warehouse and the DynamoDB vault, set up by adding a signpost. An Interface Endpoint is a private door with its own room number inside your floor, and PrivateLink is the construction method that builds that private door to any service.
Understanding the Concepts
Why use VPC Endpoints?
Without an endpoint, a private instance reaching S3 would send traffic out through a NAT Gateway to the public S3 endpoint. That costs NAT data-processing charges and the traffic leaves your VPC's private path. A VPC Endpoint removes both problems by keeping the traffic inside the AWS network.
public class WhyEndpoints {
// Without endpoint:
// Private instance → NAT Gateway → Internet → S3 public endpoint
// Cost: NAT data-processing charge per GB
// Security: traffic leaves the private network
// With Gateway Endpoint:
// Private instance → VPC Gateway Endpoint → S3 (private path)
// Cost: FREE
// Security: traffic never leaves AWS network
}
What is a Gateway Endpoint?
A Gateway Endpoint works only for S3 and DynamoDB. You create it and AWS adds a route in your subnet's route table for the service's prefix list pointing to the endpoint. It costs nothing and there are no data-processing charges. Because it is a route-table target, it only affects traffic from subnets whose route table you updated.
# Create a free Gateway Endpoint for S3
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0abc \
--service-name com.amazonaws.ap-south-1.s3 \
--route-table-ids rtb-private-a rtb-private-b
# Route automatically added to the specified route tables
# S3 traffic now goes privately, bypassing NAT
# Route table after Gateway Endpoint creation 10.0.0.0/16 → local pl-xxxxxxxx → vpce-0s3gateway (S3 prefix list → private path, FREE) 0.0.0.0/0 → nat-0gateway (other internet traffic via NAT)
What is an Interface Endpoint?
An Interface Endpoint is used for almost every other AWS service: Secrets Manager, KMS, SQS, ECR, SSM, and more. It creates an elastic network interface (ENI) with a private IP inside your subnet. Your instances reach the service through that private IP, usually via a private DNS name that resolves to it. It bills per hour and per gigabyte.
# Create an Interface Endpoint for Secrets Manager
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0abc \
--service-name com.amazonaws.ap-south-1.secretsmanager \
--vpc-endpoint-type Interface \
--subnet-ids subnet-private-a subnet-private-b \
--security-group-ids sg-endpoint \
--private-dns-enabled
# Private DNS: secretsmanager.ap-south-1.amazonaws.com
# now resolves to the private endpoint IP instead of public
What is AWS PrivateLink?
AWS PrivateLink is the technology behind Interface Endpoints. A service provider publishes an endpoint service fronted by a Network Load Balancer, and consumers create Interface Endpoints to it. This lets a partner bank expose an API to National Bank of India entirely over private IPs, with no internet exposure, no VPC peering, and no overlapping-CIDR concerns.
# PrivateLink architecture ┌──── Provider Account ────┐ ┌──── Consumer Account ────┐ │ │ │ │ │ Service behind NLB │ │ Interface Endpoint │ │ ┌──────┐ ┌──────┐ │ │ ┌──────┐ │ │ │ App │──│ NLB │─────────────│ ENI │── Consumer App │ │ └──────┘ └──────┘ │ │ └──────┘ │ │ │ │ Private IP in consumer's │ │ Endpoint Service │ │ subnet │ └───────────────────────────┘ └───────────────────────────┘ # Only the specific service is exposed, not the whole network
How are Gateway and Interface Endpoints different?
| Aspect | Gateway Endpoint | Interface Endpoint |
|---|---|---|
| Services | S3 and DynamoDB only | Most AWS services + partner services |
| Mechanism | Route table entry (prefix list) | ENI with private IP in your subnet |
| Cost | Free | Per hour + per GB |
| DNS | Uses S3/DynamoDB public DNS (traffic rerouted) | Private DNS resolves to private IP |
| Security Group | Not applicable (route-based) | Requires a Security Group on the ENI |
| Subnet placement | Not in a subnet (route-table level) | Placed in specific subnets |
public class GatewayVsInterface {
// S3 and DynamoDB: use Gateway Endpoint (free)
// Secrets Manager, KMS, SQS, ECR, SSM: use Interface Endpoint
// Partner APIs: use PrivateLink Interface Endpoint
}
How do endpoint policies provide security?
Endpoints support endpoint policies, which restrict which resources the endpoint can access. Combined with S3 bucket policies that require access via a specific VPC endpoint, this creates a strong data-exfiltration control.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowOnlyStatementsBucket",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::nbi-customer-statements/*"
}]
}
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyNonVPCEndpointAccess",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::nbi-customer-statements", "arn:aws:s3:::nbi-customer-statements/*"],
"Condition": {
"StringNotEquals": { "aws:sourceVpce": "vpce-0s3gateway" }
}
}]
}
What are common mistakes?
The first mistake is routing S3 and DynamoDB traffic through a NAT Gateway when a free Gateway Endpoint exists. This wastes money on data-processing charges.
The second mistake is forgetting to enable private DNS on an Interface Endpoint. Without it, the service's public DNS still resolves to public IPs and traffic goes through NAT.
The third mistake is not attaching a Security Group to an Interface Endpoint ENI, leaving it open to all traffic within the VPC.
# Check if you have S3 Gateway Endpoint (should exist for cost savings)
aws ec2 describe-vpc-endpoints \
--filters "Name=service-name,Values=com.amazonaws.ap-south-1.s3" \
--query 'VpcEndpoints[*].[VpcEndpointId,VpcEndpointType]'
# If empty → create one to save NAT costs
What should a senior engineer know?
A senior engineer uses Gateway Endpoints for S3 and DynamoDB in every VPC by default (they are free), and adds Interface Endpoints for other services when the security or cost benefit justifies the per-hour charge. They combine endpoint policies with resource policies for defense-in-depth data-exfiltration controls.
They also know that for SSM Session Manager to work on private instances without a NAT Gateway, they need Interface Endpoints for SSM, SSM Messages, and EC2 Messages services. And they know that PrivateLink connections are unidirectional – the consumer can reach the provider, but not the reverse.
Endpoint Strategy for Banking VPC: ┌────────────────────────┬─────────────┬──────────┐ │ Service │ Type │ Cost │ ├────────────────────────┼─────────────┼──────────┤ │ S3 │ Gateway │ Free │ │ DynamoDB │ Gateway │ Free │ │ Secrets Manager │ Interface │ Per-hour │ │ KMS │ Interface │ Per-hour │ │ ECR (container pulls) │ Interface │ Per-hour │ │ SSM (Session Manager) │ Interface │ Per-hour │ │ Partner settlement API │ PrivateLink │ Per-hour │ └────────────────────────┴─────────────┴──────────┘
Visual Overview
┌──────── VPC Endpoints: Gateway vs Interface ────────┐ │ │ │ Without Endpoint: │ │ Private Instance → NAT GW → Internet → S3 │ │ (NAT charges, traffic leaves VPC) │ │ │ │ Gateway Endpoint (S3, DynamoDB): │ │ ┌──────────────────────────────────────────┐ │ │ │ Route Table: pl-xxx → vpce-gateway │ │ │ │ Private Instance → Route → S3 (private) │ │ │ │ FREE, no data-processing charges │ │ │ └──────────────────────────────────────────┘ │ │ │ │ Interface Endpoint (Secrets Manager, KMS, etc.): │ │ ┌──────────────────────────────────────────┐ │ │ │ ENI with private IP in your subnet │ │ │ │ Private DNS resolves to private IP │ │ │ │ Private Instance → ENI → Service │ │ │ │ Per-hour + per-GB charge │ │ │ └──────────────────────────────────────────┘ │ │ │ │ PrivateLink (Partner Services): │ │ ┌──────────────────────────────────────────┐ │ │ │ Provider: NLB → Service │ │ │ │ Consumer: Interface Endpoint → ENI │ │ │ │ Only the service exposed, not the network │ │ │ │ No peering, no overlapping-CIDR issues │ │ │ └──────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────┘
Key Takeaway
A VPC Endpoint lets resources inside my VPC reach supported AWS services or partner services privately, without needing an Internet Gateway, a NAT Gateway, or public IPs. There are two kinds. A Gateway Endpoint works only for S3 and DynamoDB, it is free, and I enable it by adding a route in my subnet's route table that sends that service's traffic to the endpoint, keeping traffic on the AWS network. An Interface Endpoint is used for almost every other AWS service and for partner or custom services, and it creates an ENI with a private IP inside my subnet that my instances reach through a private DNS name.
AWS PrivateLink is the technology behind Interface Endpoints. A service provider publishes an endpoint service fronted by a Network Load Balancer, and consumers create Interface Endpoints to it, so the service is reachable entirely over private IPs. The elegant thing is that it exposes only that one service rather than connecting whole networks, so there is no peering to set up and no overlapping-CIDR concern.
The reason I use endpoints in banking is both security and cost. At National Bank of India our settlement service runs in a private subnet and reads statement files from S3 and credentials from Secrets Manager. By adding a Gateway Endpoint for S3 and an Interface Endpoint for Secrets Manager, that traffic never leaves the AWS private network and we avoid NAT data-processing charges entirely, while the code does not change at all. For a partner bank's settlement-confirmation API, we consume it through a PrivateLink Interface Endpoint.
The senior point is that endpoints are also a powerful data-exfiltration control. I attach endpoint policies that restrict which resources the endpoint can reach, and I pair them with S3 bucket policies that require access to come through a specific VPC endpoint. That means a sensitive bucket refuses any request that did not arrive through the bank's own private endpoint.
Remember one sentence: Gateway Endpoints give free private access to S3 and DynamoDB, Interface Endpoints give PrivateLink private access to everything else, and both keep traffic off the public internet.
---