Course outline

22.2

VPC Endpoints and PrivateLink

Gateway vs interface endpoints, endpoint policies, Lambda to DynamoDB without NAT, and publishing your own service.

26 min Reading + animations

Tip: tap or hover any dotted-underlined term to see what it means.

By the end of this lesson you will be able to

  • Explain why VPC endpoints exist: private access to AWS services from subnets with no internet path, no public IPs, policy control on the path, and no NAT gateway processing fee.
  • Describe exactly how a gateway endpoint works (prefix list, route tables, longest prefix match, same Region) and why nothing outside its VPC can use it.
  • Describe how an interface endpoint works (one ENI per AZ, security group, Regional and zonal names, private DNS and the two VPC DNS attributes) and who can reach it: on-premises, peered VPCs, Transit Gateway spokes, other Regions.
  • Write endpoint policies, combine them with bucket policies (aws:SourceVpce, aws:SourceVpc) and IAM, and use them as a data perimeter.
  • Pick gateway or interface endpoint for S3 and DynamoDB, fix a Lambda function in a VPC that cannot reach DynamoDB, and calculate NAT and endpoint bills.
  • Publish your own service with PrivateLink: NLB, endpoint service, allowed principals, acceptance, private DNS names, one-way connections, overlapping CIDRs, and the 2024–2025 cross-Region options.
  • Troubleshoot endpoints from the symptom: timeout vs Access Denied, DNS vs routes vs security groups.

#Why VPC endpoints exist

Every AWS service you call from code (S3, DynamoDB, SQS, KMS, Secrets Manager, the EC2 API…) is reached at a public service endpoint such as sqs.ap-south-1.amazonaws.com, which resolves to public IP addresses. An instance in a private subnet has no public IP and no route to the internet gateway, so without help it cannot call any of them.

Lesson 3.4 gave the classic fix: a NAT gateway in a public subnet, and a 0.0.0.0/0 route to it. That works, but it has three costs:

  • Money. A NAT gateway charges per hour and for every GB it processes (about $0.045 + $0.045 per GB in us-east-1). Heavy S3 or DynamoDB traffic can make NAT the biggest line on the bill.
  • An internet path. The subnet now can reach anything on the internet. Some regulators and security teams forbid that for data tiers.
  • Less control. The service sees the NAT gateway’s public IP, so you cannot say “this bucket only for requests from my VPC”.

A VPC endpoint gives the subnet a private way to reach the service without an internet gateway, a NAT device, a VPN or a public IP. Traffic goes to the service over the AWS network, the service can tell which endpoint and VPC the request came through, and you can attach a policy to the endpoint itself.

#The kinds of VPC endpoint

TypeWhat it isServicesBuilt onCost
Gateway endpointA target in route tables, reached through a prefix-list routeS3 and DynamoDB onlyVPC routing (not PrivateLink)Free
Interface endpointENIs with private IPs in your subnetsMost AWS services, your own and partners’ servicesAWS PrivateLinkPer AZ-hour + per GB
Gateway Load Balancer endpointA route-table next hop that sends traffic to firewall appliancesA Gateway Load Balancer’s endpoint servicePrivateLinkPer AZ-hour + per GB
Resource and service-network endpoints (2024)Access to one shared resource (a database, an IP, a domain) or a VPC Lattice service networkResources shared through AWS RAMPrivateLink / VPC LatticePer hour + per GB

The exam is about the first two, with the third as “third-party appliances”. Interface endpoints are the reason PrivateLink exists as a name: it is the technology that places a private entry point for a service inside your VPC so that your application believes the service lives in its own network.

#Gateway endpoints in depth

#How a gateway endpoint steers traffic

You create a gateway endpoint for a service name such as com.amazonaws.ap-south-1.s3 or com.amazonaws.ap-south-1.dynamodb, pick the VPC, and tick the route tables that should use it.

  1. AWS adds one route to each ticked route table: destination = the AWS-managed prefix list for the service in this Region (pl-…, a named list of all its address ranges), target = the endpoint (vpce-…). You can see that route but cannot edit or delete it; you remove it by disassociating the route table or deleting the endpoint.
  2. Your code keeps calling the normal name, for example s3.ap-south-1.amazonaws.com. DNS still returns a public S3 address. Nothing in the application changes.
  3. The VPC router now has two candidate routes for that address: 0.0.0.0/0 (to NAT or the internet gateway) and the prefix list. The more specific route wins (longest prefix match, lesson 3.3), so S3 traffic goes to the endpoint and everything else keeps its old path.
  4. A route that names the service’s exact IP range would beat the endpoint route, and traffic for the same service in another Region does not match the prefix list at all, so it follows 0.0.0.0/0.

Rules that follow from “it is just a route”:

  • It works per route table, not per VPC. A subnet whose route table you did not tick still uses NAT (and pays) or has no path at all.
  • One route table can have an S3 endpoint route and a DynamoDB endpoint route, but not two routes to the same service.
  • Adding the route resets open TCP connections to the service from those subnets, because the path changes.

Gateway endpoint: one route, chosen by longest prefix match

A Chattogram logistics firm’s private servers pull about 2 TB a month from S3. Watch how a prefix-list route steals S3 traffic from the NAT gateway, and the two ways it silently does not.

Scenario

No endpoint yet. Every S3 byte goes through the NAT gateway.

VPC10.0.0.0/16
Subnet B
Subnet A
Public subnet
Server B
Server A
NAT gateway
Amazon S3
GET parcel.csv

Route table of subnet A

10.0.0.0/16

local

0.0.0.0/0

nat-0f12

Step 1 of 2
1

Server A calls s3.ap-south-1.amazonaws.com and gets a public S3 address. Its route table has only local and 0.0.0.0/0, so the packet takes the default route to the NAT gateway.

#Security groups, network ACLs and DNS

A gateway endpoint has no ENI, no IP address and no security group of its own. The instances still talk to the service’s public addresses, so:

  • The instance’s security group must allow outbound TCP 443 to the service. You can use the prefix list as the destination of the rule (pl-…).
  • Network ACLs cannot reference prefix lists: allow the service’s CIDR ranges (listed in the prefix list) or keep the default allow-all.
  • Keep the VPC’s DNS resolution on so the instances can resolve the service name; to use DNS record types other than the default (IPv6 or dual-stack answers), both enableDnsSupport and enableDnsHostnames must be on.

#Limits of a gateway endpoint

  • S3 and DynamoDB only, and only in the endpoint’s own Region.
  • Only for traffic that starts inside its VPC. Traffic that arrives over Site-to-Site VPN, Direct Connect, VPC peering or a transit gateway cannot be forwarded to it: “a gateway endpoint can never be extended out of its VPC”.
  • Free: no hourly or per-GB fee. Normal S3 and DynamoDB request charges still apply.
  • Quotas: 20 gateway endpoints per Region per account by default (adjustable), up to 255 per VPC. No bandwidth limit of its own.
  • IPv6: the IP address type can be IPv4, IPv6 (IPv6-only subnets) or dual-stack.
  • An endpoint policy can be attached (below). For gateway endpoints its Principal must be *; filter callers with the aws:PrincipalArn condition.

#Interface endpoints in depth

#What gets created

An interface endpoint (PrivateLink) puts an endpoint network interface in each subnet you choose, one subnet per AZ. Each ENI:

  • gets a private IP from its subnet that never changes during the endpoint’s life (you can pick it yourself);
  • is requester-managed: you see it in your account but cannot modify or detach it;
  • has one or more security groups. If you choose none, AWS attaches the VPC’s default security group, which only allows traffic from its own members, a classic source of timeouts;
  • answers TCP (for AWS services, HTTPS on 443) and never answers ping: test with nc -vz or curl, not ICMP.

Interface endpoints exist for most AWS services: SQS, SNS, KMS, Secrets Manager, STS, ECR, CloudWatch Logs, the EC2 API, Lambda, Systems Manager, and also S3 and DynamoDB (DynamoDB since 2024). If the service is S3 or DynamoDB and the caller is in the same VPC, the gateway endpoint is still the cheaper choice.

#DNS decides whether it is used

An interface endpoint only receives traffic that is sent to its IPs. Which IP a client uses depends entirely on DNS:

  • Regional and zonal endpoint names. Every interface endpoint gets names such as vpce-0a1b2c3d-x1y2.sqs.ap-south-1.vpce.amazonaws.com (Regional, all AZs) and vpce-0a1b2c3d-x1y2-ap-south-1a.sqs.ap-south-1.vpce.amazonaws.com (zonal, one AZ, keeps traffic in that AZ). These records are in public DNS but resolve to the private IPs, so anything that can route into the VPC can use them with --endpoint-url or an SDK endpoint override.
  • Private DNS (on by default for AWS services). AWS creates a hidden private hosted zone in your VPC that maps the normal service name (sqs.ap-south-1.amazonaws.com) to the endpoint ENIs. Existing code and SDKs use the endpoint with no change. It requires both VPC attributes enableDnsSupport and enableDnsHostnames; with either one off you cannot turn private DNS on.
  • That hidden zone works only inside the endpoint’s VPC. Peered VPCs, Transit Gateway spokes and on-premises servers do not see it: they need the endpoint-specific name, a Route 53 private hosted zone you create and associate, or Resolver forwarding (lesson 8.5).
  • S3 special case: “private DNS only for inbound endpoints”. In-VPC clients keep resolving S3 to public addresses and use the free gateway endpoint; queries arriving at a Route 53 Resolver inbound endpoint (from on-premises) get the interface endpoint’s IPs. AWS refuses this setting if the VPC has no S3 gateway endpoint. Details in lesson 10.10.
  • DynamoDB special case: DynamoDB interface endpoints do not support private DNS, and AWS warns against overriding dynamodb.<region>.amazonaws.com with your own private zone. Clients must use the endpoint-specific URL.

With a single AZ, DNS returns one IP and every AZ’s clients cross to it (an extra AZ hop of latency, and an AZ outage cuts them all off; PrivateLink stopped charging inter-AZ data transfer in April 2022). With several AZs, DNS returns all healthy ENIs.

Interface endpoint for SQS: the ENI only helps if DNS points at it

SQS has no gateway endpoint, so an order app in a private subnet reaches it through an interface endpoint: one ENI per AZ, each with a private IP and a security group. The VPC also has a NAT gateway, which hides mistakes.

Scenario

The normal SQS name now resolves to the ENIs. No code change.

VPC10.0.0.0/16
AZ a
AZ b
Order app
Endpoint ENI10.0.1.40
Endpoint ENI10.0.2.40
NAT gateway
Amazon SQS

DNS lookup inside the VPC

Question

sqs.ap-south-1.amazonaws.com

Answer

10.0.1.40, 10.0.2.40

Why

hidden private zone

Step 1 of 3
1

Private DNS is on and the VPC has both DNS attributes enabled, so AWS created a hidden private hosted zone for sqs.ap-south-1.amazonaws.com. The SDK asks the usual name and gets the ENIs’ private IPs.

#Reaching an interface endpoint from outside the VPC

Because an interface endpoint is a set of real private IPs, anything that can route to those IPs can use it:

CallerGateway endpoint in VPC XInterface endpoint in VPC X
Instance in VPC XYesYes
Peered VPC (lesson 22.1)No (no edge-to-edge routing)Yes, endpoint-specific name or a shared private hosted zone
Transit Gateway spoke (22.6)NoYes: the “shared endpoints VPC” pattern
On-premises over Site-to-Site VPN (22.4) or Direct Connect private/transit VIF (22.5)NoYes, with DNS forwarding to a Resolver inbound endpoint or the endpoint-specific name
VPC in another RegionNoYes, over inter-Region peering or TGW peering

The security group of the endpoint must allow 443 from those callers’ ranges too (the office CIDR, the spoke CIDRs), not only from the VPC.

From the data centre: the gateway endpoint is out of reach, the interface endpoint is not

A bank in Motijheel reaches its VPC over Direct Connect and must put nightly reports into S3 without the internet. The VPC has both kinds of S3 endpoint and a Route 53 Resolver inbound endpoint.

Scenario

The network team hopes the free gateway endpoint will carry on-premises traffic too.

Data centre
VPC10.0.0.0/16
Report server
Direct Connect
Gateway endpoint
Resolver inbound10.0.3.10
Interface endpoint10.0.2.20
Amazon S3
to S3 public IP
Step 1 of 2
1

The report server sends to S3’s public address over Direct Connect (a private VIF), hoping the VPC will hand it to the gateway endpoint.

#Cost, bandwidth and quotas

Prices are us-east-1 list prices (checked October 2026); most Regions are close, some slightly higher.

  • Hourly: about $0.01 per endpoint per AZ-hour. One endpoint in 3 AZs for a 730-hour month: 3 × 730 × $0.01 = $21.90. Ten AWS services × 3 AZs = $219 a month before any data, a real cost in big VPCs.
  • Data processed: $0.01 per GB for the first PB a month, $0.006 for the next 4 PB, $0.004 above 5 PB (counted per Region across your endpoints).
  • Compared with NAT: NAT gateway ~$0.045 per hour + $0.045 per GB. At 1 TB a month: NAT ≈ $32.85 + $46.08 = $79; interface endpoint in 2 AZs ≈ $14.60 + $10.24 = $25; gateway endpoint $0 (S3 and DynamoDB only).
  • Bandwidth: 10 Gbps per AZ by default, scaling automatically to 100 Gbps per AZ. MTU 8,500 bytes; larger packets are dropped and Path MTU Discovery is not supported (MSS clamping is applied).
  • Quotas: 50 interface plus Gateway Load Balancer endpoints per VPC (adjustable); endpoint policy up to 20,480 characters.

#Cross-Region interface endpoints

Classic rule (and the exam’s): an interface endpoint connects to a service in its own Region; to reach another Region you route to an endpoint there over inter-Region peering or Transit Gateway peering. Two newer options exist:

  • November 2024: a provider can make its own endpoint service available in other Regions, and consumers create the interface endpoint in their Region. The provider pays an hourly fee per remote Region; the consumer pays normal endpoint fees plus inter-Region data transfer.
  • November 2025: some AWS services can be reached through a cross-Region interface endpoint (--service-region): S3, IAM, KMS, ECR, ECS, Lambda, Data Firehose, Managed Service for Apache Flink, Route 53. It needs the vpce:AllowMultiRegion permission in IAM and in SCPs, uses only the Regional DNS name (no zonal names), and AWS still recommends same-Region endpoints for latency and cost.

If an exam question offers both, “interface endpoint in the other Region over peering” and “cross-Region endpoint” are both private; pick what the question’s keywords (fewest components, no peering) point to, and remember that gateway endpoints never cross Regions.

#Endpoint policies

An endpoint policy is an IAM resource-based policy attached to the endpoint. It says which principals may use this endpoint for which actions on which resources.

  • Supported on gateway endpoints and on interface endpoints for AWS services that support it (most do). One policy per endpoint, changeable at any time; changes take a few minutes.
  • The default policy is full access ("Principal": "*", "Action": "*", "Resource": "*").
  • It never grants anything. A request through the endpoint must be allowed by IAM and the endpoint policy and any resource policy (bucket policy, key policy), and no SCP may deny it (lesson 2.2).
  • It only sees requests that pass through the endpoint. A request from a laptop on the internet never meets it.
  • For your own or partners’ endpoint services there is no endpoint policy to tune: AWS allows full access, and the provider controls access with allowed principals.

The classic use is a data perimeter in both directions:

{
  "Statement": [
    {
      "Sid": "OnlyOurOrganisationsBuckets",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": { "StringEquals": { "aws:ResourceOrgID": "o-a1b2c3d4e5" } }
    }
  ]
}

This endpoint policy lets instances use only buckets owned by the company’s AWS Organization, so malware with valid credentials cannot upload stolen data to an attacker’s bucket through the endpoint. The other direction is the bucket policy with aws:SourceVpce (one endpoint) or aws:SourceVpc (any endpoint in one VPC), already shown in lesson 10.2 and 10.10: this bucket accepts requests only through our endpoint, so leaked keys used from outside are refused. Through an endpoint, aws:SourceIp does not match (the request has no public source address); use aws:VpcSourceIp for private ranges.

For DynamoDB the same idea limits an endpoint to named tables, for example "Resource": "arn:aws:dynamodb:ap-south-1:111122223333:table/Orders".

Endpoint policy and bucket policy: two locks on one door

The endpoint policy says “through this endpoint, only our buckets”. The bucket policy says “this bucket, only through our endpoint”. IAM still has to allow the call. All three must agree.

Scenario

VPC10.0.0.0/16
Billing server
S3 endpointvpce-0a1b
Our bucketinvoices-example
Outside bucketother account
Stolen keys
PutObject
Step 1 of 2
1

The billing server, with an IAM role that allows s3:PutObject on invoices-example, uploads through the endpoint.

#Gateway or interface endpoint for S3 and DynamoDB?

Both services support both types, and you can have both in the same VPC.

QuestionGateway endpointInterface endpoint
Caller in the same VPC, same RegionBest: free, no DNS changeWorks, costs per hour and per GB
Caller on-premises (VPN, Direct Connect)ImpossibleYes
Caller in a peered VPC or a TGW spokeImpossibleYes
Bucket or table in another RegionImpossibleYes (endpoint in that Region)
Addresses usedPublic service addressesPrivate IPs from your subnets
Security group on the endpointNoneYes
DNSUnchangedS3: private DNS (optionally inbound only); DynamoDB: endpoint URL only

Self-checkQuestion

EC2 instances in a VPC read 4 TB a month from S3. A new on-premises reporting system connected by Site-to-Site VPN must write to the same bucket privately. What is the most cost-effective design?

#Lambda in a VPC reaching DynamoDB

Lesson 15.3 explained why: a function attached to your VPC gets ENIs with private IPs only, never a public IP, even in a public subnet. So it loses its default internet access, and DynamoDB, a public service, becomes unreachable. Two fixes:

  • NAT gateway: private subnet → NAT gateway in a public subnet → internet gateway → DynamoDB. Works for any destination, but costs per hour and per GB.
  • Gateway endpoint for DynamoDB (best practice): create it, associate the private subnets’ route tables, done. Free, no internet path, no code change.

Most real functions use both: endpoints for AWS services (gateway for S3 and DynamoDB, interface for Secrets Manager, SQS…), and a NAT gateway only for third-party APIs on the internet.

Lambda in a VPC reading DynamoDB: NAT gateway or gateway endpoint

A ride-sharing app’s fare function was attached to the VPC to reach a private database (lesson 15.3). It also reads about 3 TB a month from DynamoDB.

Scenario

The function was just attached to the VPC. Nothing else changed.

VPC10.0.0.0/16
Private subnet
Public subnet
Fare functionno route
DynamoDB
Step 1 of 2
1

Inside your VPC the function’s ENI has only a private IP and never gets a public one, even in a public subnet. DynamoDB’s endpoint is a public address, and this subnet has no route to it.

So far the provider was AWS. With PrivateLink you can be the provider: publish a service so that other VPCs and other AWS accounts reach it privately, without peering, without the internet, and without exposing anything else in your network. Lesson 6.3 introduced the idea from the load balancer side; here is the whole workflow.

#How an endpoint service works

  1. Provider: put the application behind a Network Load Balancer (or a Gateway Load Balancer for appliances) in at least two AZs. An HTTP app with path rules can sit behind an NLB with an ALB as its target.
  2. Provider: create a VPC endpoint service from that NLB. You get a service name such as com.amazonaws.vpce.ap-south-1.vpce-svc-0f1e2d3c4b5a69788.
  3. Provider: add allowed principals (account IDs, IAM roles or users, or *). By default nobody may connect.
  4. Provider: choose acceptance required to approve each connection by hand, or accept automatically.
  5. Consumer: create an interface endpoint for that service name in their VPC (subnets in AZs the service offers) with a security group.
  6. Provider: accept the connection (pendingAcceptance → available). The provider can reject or remove a connection later.

Consequences that exam questions test:

  • Overlapping CIDRs do not matter. No routes are exchanged between the VPCs; the consumer talks to its own ENI, PrivateLink hands the connection to the NLB.
  • One service, not a network. The consumer reaches only that NLB’s listeners, nothing else in the provider VPC, and the provider sees nothing of the consumer VPC.
  • One-way. Only the consumer opens connections; replies flow back, but the provider cannot start a connection into the consumer. Two-way needs two endpoint services.
  • Source IP. The application sees the NLB’s private IP, not the consumer’s. Enable proxy protocol v2 on the NLB target group to receive the consumer’s IP and endpoint ID.
  • AZs. The consumer can only use AZs the service is in. AZ names differ between accounts (ap-south-1a here may be another building there), so match by AZ ID (aps1-az1).
  • Scale. Built for many consumers: hundreds or thousands of customer VPCs can connect to one service.
  • Cost. The consumer pays the interface endpoint’s hours and per GB; the provider pays for the NLB.
  • Cross-Region. Since November 2024 the provider can offer the service in other Regions (see above); otherwise consumers in other Regions reach it over peering or a transit gateway.

#Private DNS names for an endpoint service

Consumers can always use the endpoint-specific names. A provider can also attach one private DNS name, such as api.fintech.example, so consumers call a friendly name that resolves to their own endpoint ENIs inside their VPC (and to the public endpoint outside it, if one exists). Before consumers can use it, the provider must prove it owns the domain: AWS gives a TXT record name and value, the provider publishes it in public DNS, and the verification status must become verified. If verification later fails, new connections are refused; existing ones keep working. Gateway Load Balancer endpoint services do not support private DNS names.

PrivateLink endpoint service: a SaaS API for banks with the same CIDR

A Dhaka fintech sells a fraud-scoring API to banks. Both sides use 10.0.0.0/16, so peering is impossible. The fintech publishes its NLB as an endpoint service; each bank creates an interface endpoint.

Scenario

The fintech created the endpoint service with “acceptance required” and allow-listed the bank’s account.

Bank VPC10.0.0.0/16
Fintech VPC10.0.0.0/16
Loan app10.0.1.15
Interface endpoint10.0.1.80pendingAcceptance
NLB10.0.4.9
Scoring API10.0.1.15
Step 1 of 2
1

The bank creates an interface endpoint for com.amazonaws.vpce.ap-south-1.vpce-svc-0f1e… in its subnets. Because its account is an allowed principal, the request is accepted for review.

VPC peeringPrivateLink endpoint service
What is sharedWhole networks (both CIDRs)One service behind an NLB
Overlapping CIDRsNot allowedFine
DirectionBoth waysConsumer → provider only
ScalePairs; mesh grows as n(n−1)/2One service, thousands of consumers
CostNo hourly fee, data transfer onlyEndpoint hours + per GB, plus the NLB
Typical useYour own VPCs talking freelySaaS, shared platform services, partners

#Gateway Load Balancer endpoints and VPC Lattice, in brief

  • A Gateway Load Balancer endpoint is a PrivateLink endpoint that you use as a route-table next hop to send traffic through a fleet of third-party firewalls or IDS appliances behind a Gateway Load Balancer (GENEVE, lesson 6.3). AWS Network Firewall uses the same idea (lesson 22.7).
  • VPC Lattice (2023) connects services across VPCs and accounts at the application layer with its own auth policies; since late 2024 PrivateLink resource endpoints and service-network endpoints reach a single shared resource (a database, an IP address, a domain name) or a whole Lattice service network without a load balancer. Rarely the exam answer yet; know the names.

#Choosing an endpoint

  1. What is the service?

    S3 or DynamoDB → a gateway endpoint is possible. Any other AWS service → interface endpoint. Your own or a partner’s service → interface endpoint to an endpoint service (PrivateLink).

  2. Where is the caller?

    Same VPC, same Region → gateway endpoint for S3 and DynamoDB. Another VPC in the Region → its own gateway endpoint, or a shared interface endpoint for many VPCs. On-premises or another Region → interface endpoint, plus DNS for the caller.

  3. Make DNS point at it

    Private DNS on (both VPC attributes enabled) for in-VPC callers; endpoint-specific names, private hosted zones or Resolver forwarding for everyone else; DynamoDB interface endpoints by URL only.

  4. Lock it down and size it

    Endpoint security group allows 443 from the real callers; endpoint policy limits resources; bucket or key policies require aws:SourceVpce; at least two AZs; count AZ-hours and GB before adding twenty endpoints to every VPC.

Which endpoint? Pick the caller and the target

Choose where the request starts and what it calls. The answer says which endpoint to build, why the tempting alternatives fail, and what each option would cost for your monthly volume.

1. Where is the caller?

2. What does it call?

4. AZs for an interface endpoint

#What goes wrong

The slides’ first advice for endpoint trouble: check the DNS settings of the VPC, then the route tables. Go from the symptom:

SymptomLikely causeFix
S3 or DynamoDB still billed through NAT after adding a gateway endpointSubnet’s route table not associated, or the bucket is in another RegionAssociate the route table; regional design or interface endpoint
Timeout from a subnet with no NATNo endpoint route in that route table; or an interface endpoint whose name still resolves to public IPsAssociate route table; enable private DNS (and both VPC DNS attributes) or use the endpoint name
Interface endpoint exists, NAT bytes unchanged, endpoint metrics near zeroPrivate DNS off, so clients still resolve public IPsEnable private DNS
Timeout to an interface endpointEndpoint security group (default SG) does not allow 443 from the client; NACL blocksAllow 443 from client SG/CIDR
Cannot enable private DNSenableDnsHostnames or enableDnsSupport off; or another private zone already claims the nameTurn on both attributes; remove the conflicting zone
Access Denied through the endpointEndpoint policy too narrow, bucket policy condition wrong (aws:SourceIp instead of aws:SourceVpce), or IAM missingFix the policy, not the network
On-premises cannot use S3 privatelyOnly a gateway endpoint was built, or on-prem DNS not forwardedInterface endpoint + Resolver inbound endpoint
Peered VPC or TGW spoke cannot use the endpointIt is a gateway endpoint (edge-to-edge), or the spoke does not resolve the private nameOwn gateway endpoint; shared interface endpoint + private hosted zone
ping to the endpoint fails but the app worksEndpoint ENIs never answer ICMPTest with nc -vz or curl
Consumer cannot create an endpoint for a partner’s serviceNot an allowed principal, or AZ not offered (compare AZ IDs)Provider adds the principal or AZs
Consumer endpoint stuck in pendingAcceptanceProvider has acceptance required and has not acceptedProvider runs accept-vpc-endpoint-connections
Large uploads hang through an endpointPackets above 8,500 bytes are dropped; no PMTUDKeep MTU at or below 8,500 (usually automatic with MSS clamping)

#How it is used in system design

  • Private-only data tiers: no NAT at all; gateway endpoints for S3 and DynamoDB, interface endpoints for KMS, Secrets Manager, SQS, CloudWatch Logs, ECR, STS and Systems Manager. Containers in private subnets pulling from ECR need the ecr.api, ecr.dkr interface endpoints and the S3 gateway endpoint (image layers live in S3).
  • Data perimeter: endpoint policies allowing only the organisation’s resources, bucket and key policies allowing only the organisation’s endpoints or VPCs, enforced with SCPs.
  • Shared endpoints VPC: in a hub-and-spoke network with Transit Gateway, one set of interface endpoints in a central VPC and Route 53 private hosted zones shared with the spokes, instead of 20 endpoints × 3 AZs in every VPC. Heavy S3 users keep their own free gateway endpoints.
  • Hybrid access: on-premises reaches AWS APIs and S3 through interface endpoints over Direct Connect, with Resolver inbound endpoints for DNS.
  • SaaS and platform teams: a payments or identity service published once with PrivateLink and consumed by hundreds of VPCs in many accounts, even with overlapping CIDRs. Marketplace SaaS vendors deliver the same way.

#Try it yourself

# 1. Find the S3 and DynamoDB prefix lists in Mumbai (what a gateway endpoint route points at)
aws ec2 describe-prefix-lists --region ap-south-1 \
  --query "PrefixLists[].[PrefixListName,PrefixListId]" --output text
# com.amazonaws.ap-south-1.dynamodb    pl-66a5400f
# com.amazonaws.ap-south-1.s3          pl-6ca54005

# 2. Gateway endpoints for S3 and DynamoDB on the private route tables
aws ec2 create-vpc-endpoint --vpc-id vpc-0a1b2c3d4e5f67890 \
  --vpc-endpoint-type Gateway --service-name com.amazonaws.ap-south-1.s3 \
  --route-table-ids rtb-0aa11bb22cc33dd44 rtb-0ee55ff66aa77bb88
aws ec2 create-vpc-endpoint --vpc-id vpc-0a1b2c3d4e5f67890 \
  --vpc-endpoint-type Gateway --service-name com.amazonaws.ap-south-1.dynamodb \
  --route-table-ids rtb-0aa11bb22cc33dd44

# 3. The route AWS added (destination pl-..., target vpce-...)
aws ec2 describe-route-tables --route-table-ids rtb-0aa11bb22cc33dd44 \
  --query "RouteTables[].Routes[?DestinationPrefixListId]"
# [[{"DestinationPrefixListId": "pl-6ca54005", "GatewayId": "vpce-0a1b2c3d4e5f60718", "State": "active", ...}]]

# 4. Both DNS attributes on, then an SQS interface endpoint in two AZs with private DNS
aws ec2 modify-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --enable-dns-support "{\"Value\":true}"
aws ec2 modify-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --enable-dns-hostnames "{\"Value\":true}"
aws ec2 create-vpc-endpoint --vpc-id vpc-0a1b2c3d4e5f67890 \
  --vpc-endpoint-type Interface --service-name com.amazonaws.ap-south-1.sqs \
  --subnet-ids subnet-0a1b2c3d4e5f60001 subnet-0a1b2c3d4e5f60002 \
  --security-group-ids sg-0endpoint443example --private-dns-enabled

# 5. From an instance: does the normal name resolve to the ENIs? Is 443 open?
dig +short sqs.ap-south-1.amazonaws.com
# 10.0.1.40
# 10.0.2.40
nc -vz sqs.ap-south-1.amazonaws.com 443
# Connection to sqs.ap-south-1.amazonaws.com (10.0.1.40) 443 port [tcp/https] succeeded!

# 6. Restrict the S3 gateway endpoint to the organisation's buckets
aws ec2 modify-vpc-endpoint --vpc-endpoint-id vpce-0a1b2c3d4e5f60718 \
  --policy-document file://only-our-buckets.json

# 7. Provider: publish an NLB as an endpoint service, allow one bank, accept its request
aws ec2 create-vpc-endpoint-service-configuration \
  --network-load-balancer-arns arn:aws:elasticloadbalancing:ap-south-1:111122223333:loadbalancer/net/score-nlb/0a1b2c3d4e5f6789 \
  --acceptance-required --private-dns-name api.fintech.example
aws ec2 modify-vpc-endpoint-service-permissions --service-id vpce-svc-0f1e2d3c4b5a69788 \
  --add-allowed-principals arn:aws:iam::444455556666:root
aws ec2 describe-vpc-endpoint-connections --filters Name=service-id,Values=vpce-svc-0f1e2d3c4b5a69788 \
  --query "VpcEndpointConnections[].[VpcEndpointId,VpcEndpointOwner,VpcEndpointState]" --output text
# vpce-0c9d8e7f6a5b43210   444455556666   pendingAcceptance
aws ec2 accept-vpc-endpoint-connections --service-id vpce-svc-0f1e2d3c4b5a69788 \
  --vpc-endpoint-ids vpce-0c9d8e7f6a5b43210

# 8. Consumer (the bank's account): connect to the service
aws ec2 create-vpc-endpoint --vpc-id vpc-0b2c3d4e5f6a78901 --vpc-endpoint-type Interface \
  --service-name com.amazonaws.vpce.ap-south-1.vpce-svc-0f1e2d3c4b5a69788 \
  --subnet-ids subnet-0c1d2e3f4a5b60001 subnet-0c1d2e3f4a5b60002 \
  --security-group-ids sg-0bankclients443example

Then check the provider’s domain verification with aws ec2 describe-vpc-endpoint-service-configurations --query "ServiceConfigurations[].PrivateDnsNameConfiguration", publish the TXT record it shows, and watch the state become verified.

#Summary

Key takeaways

  • VPC endpoints let private subnets reach AWS services with no internet gateway, NAT device, VPN or public IP; they remove the internet path and the NAT per-GB fee and add policy control. (Traffic to AWS services stays on the AWS network either way.)
  • Gateway endpoint: S3 and DynamoDB only; a prefix-list route in the route tables you tick; longest prefix match beats 0.0.0.0/0; free; same Region; no ENI, IP or security group; never usable from on-premises, peered VPCs, Transit Gateway or other Regions. The “most cost-effective” exam answer.
  • Interface endpoint (PrivateLink): one ENI per AZ with a private IP and a security group (default SG if you pick none); DNS decides whether it is used: Regional/zonal names, or private DNS which needs enableDnsSupport and enableDnsHostnames and works only inside its VPC; ~$0.01 per AZ-hour + ~$0.01 per GB; reachable from on-premises, peered VPCs, spokes and other Regions; no ping.
  • S3 can use “private DNS only for inbound endpoints” (requires a gateway endpoint); DynamoDB interface endpoints have no private DNS.
  • Endpoint policies: resource policies on the endpoint, default full access, they only restrict; pair with bucket policies on aws:SourceVpce / aws:SourceVpc for a two-way data perimeter.
  • S3 choice: in-VPC → gateway; on-premises, other VPC, other Region → interface. Lambda in a VPC → DynamoDB: gateway endpoint + route table update.
  • Endpoint service: NLB (or GWLB) → endpoint service → allowed principals → acceptance → consumer interface endpoint; overlapping CIDRs fine, one-way, one service only; proxy protocol v2 for client IPs; match AZ IDs; private DNS name verified by TXT record.
  • New since 2024: cross-Region endpoint services (Nov 2024), cross-Region interface endpoints for some AWS services (Nov 2025), resource and service-network endpoints (VPC Lattice). Exam default: same-Region endpoints.
  • Troubleshoot by symptom: timeout → DNS, route table, security group; Access Denied → endpoint, bucket or IAM policy.