Reaching Cloud Services Privately - Endpoints and PrivateLink
- A cloud service such as S3 or SQS lives on public IPs by default. To reach it from a private subnet without a NAT gateway or an internet gateway, give the service a private path into your VPC.
- AWS has two kinds. A gateway endpoint (S3 and DynamoDB only) is a route-table entry pointing a prefix list at the endpoint. It is free. An interface endpoint (PrivateLink) is an ENI with a private IP in your subnet plus a DNS override. It is billed per hour and per GB.
- With an interface endpoint the work is done by DNS: the service's normal name resolves to the ENI's private IP. Turn private DNS off and the name resolves to the public IP, so traffic goes the old way.
- PrivateLink is not peering. It exposes one service, one way (consumer to provider), and it works with overlapping CIDRs. The endpoint is also not the service: IAM and resource policies still apply.
- GCP calls the pieces Private Google Access and Private Service Connect. Azure calls them service endpoints and Private Endpoint (Private Link).
Mental model
A company mailroom needs to send documents to the bank across town. Option one: a courier walks out the front door, crosses the street and enters the bank's public lobby. Option two: the company and the bank agree on a sealed internal tube that ends in a slot in the mailroom wall. Staff post the envelope in the slot and never go outside. A gateway endpoint is like adding a line to the mailroom's directory: "anything for the bank, use the tube". An interface endpoint is a slot installed in your own wall with its own label, so the name "Bank" now points at the slot instead of the lobby.
Where it breaks: the tube gets your envelope to the bank's front desk, nothing more. The bank still checks who sent it and what it is allowed to do. The endpoint is a path, not a permission.
It is a local proxy address for a remote dependency. Instead of calling sqs.us-east-1.amazonaws.com at some public address, your code (unchanged) reaches a private IP that forwards to the same API. Like service discovery, the trick is that the name stays the same and the answer changes. A gateway endpoint is the routing flavour of this trick (a more specific route wins, see routing in a VPC). An interface endpoint is the DNS flavour.
Where it breaks: a sidecar is yours to configure and secure. An endpoint is a managed object that carries its own security group and its own endpoint policy, and a wrong one fails with a timeout or AccessDenied, not a clean connection error.
How it works
Start from the problem. A private subnet has no route to an internet gateway (cloud network model, routing in a VPC). Its instances can still reach public AWS services if a NAT gateway forwards them, but then every byte is billed as NAT data processing and every request leaves via a public IP. Endpoints remove that hop.
Three paths to the same service
Gateway endpoints: a route, not a device
A gateway endpoint exists only for S3 and DynamoDB. When you create one you pick the route tables to associate with it, and AWS adds a route whose destination is a managed prefix list (a named set of the service's public CIDRs) and whose target is the endpoint, vpce-... (AWS gateway endpoints). Because that prefix list is more specific than 0.0.0.0/0, longest-prefix match sends S3-bound packets to the endpoint and everything else to the NAT gateway, as in routing in a VPC.
Nothing about the name changes. s3.us-east-1.amazonaws.com still resolves to public IPs; the route table recognises those IPs as members of the S3 prefix list and diverts them. There is no ENI, no security group, and no charge for the endpoint or the data it carries (AWS PrivateLink pricing, as of 2026-10).
Interface endpoints: an ENI plus a DNS answer
An interface endpoint creates an elastic network interface with a private IP in each subnet you choose (one per AZ) and attaches a security group to it (AWS interface endpoints). Reaching the ENI is just in-VPC traffic covered by the local route. What makes applications use it is private DNS: when enabled, AWS associates a hidden private hosted zone with your VPC so the service's regular name resolves to the ENI addresses.
Before and after, as dig would show it (addresses are illustrative; the public answers change from query to query):
One private IP per endpoint ENI, so a three-AZ endpoint returns three. Private DNS only works if the VPC has both enableDnsSupport and enableDnsHostnames set to true (AWS interface endpoints).
The VPC resolver and where private DNS lives
Every instance asks the Amazon-provided DNS resolver, reachable at 169.254.169.253 and at the VPC base address plus 2 (10.0.0.2 for a 10.0.0.0/16 VPC) (AWS DNS in your VPC). It answers from private hosted zones associated with the VPC first and falls back to public DNS. That is split-horizon DNS: the same name gives different answers depending on who asks. Recursion and record types are explained in DNS and DNS records and routing; here the point is only that the resolver can lie to you, on purpose, inside the VPC.
Cross-cloud map
| Concept | AWS | GCP | Azure | Gotcha |
|---|---|---|---|---|
| Route-level private path to storage | Gateway endpoint (S3, DynamoDB), prefix list route | Private Google Access, enabled per subnet; traffic goes to Google public IPs but stays on Google's network | Service endpoint, enabled per subnet; adds a VNet identity to the service firewall | The service keeps its public IP in all three, and none of these gives the service a private IP |
| Private IP for a service in your network | Interface endpoint (ENI, PrivateLink) | Private Service Connect endpoint (internal IP you choose, forwarding rule) | Private Endpoint (NIC with a private IP, Private Link) | Each costs money and each needs DNS to be correct |
| Publish your own service privately | Endpoint service (NLB or GWLB behind it) | Private Service Connect service attachment (behind an internal load balancer) | Private Link service (behind a Standard Load Balancer) | One-way, consumer to provider. Overlapping CIDRs are fine |
| Private DNS for the above | Private hosted zone, hidden one with private DNS on | Cloud DNS private zone, such as googleapis.com pointed at the VIP | Private DNS zone such as privatelink.blob.core.windows.net | Link the zone to the VPC or VNet or the name stays public |
| Hybrid DNS | Route 53 Resolver inbound and outbound endpoints | Cloud DNS forwarding and peering | Azure DNS Private Resolver | On-premises resolvers need an explicit forwarder |
For GCP the product view (Private Google Access in the exam context) is on the gcp-ace DNS, NAT and IPs page. This page keeps the vendor-neutral idea.
Choosing an endpoint type
| Type | Mechanism | Services | Cost (AWS) | Reachable from on-prem |
|---|---|---|---|---|
| Gateway endpoint | Route table entry, prefix list to vpce | S3 and DynamoDB only | Free | No, the route lives in the VPC route table only |
| Interface endpoint | ENI per AZ, security group, private DNS | Most AWS APIs, partner and your own endpoint services, and S3 as well | Per hour per AZ plus per GB | Yes, over VPN or Direct Connect, if DNS resolves to the ENI |
Reading it: S3 has both kinds. Use the gateway endpoint inside the VPC because it is free; use an S3 interface endpoint when on-premises or a peered network must reach S3 privately (the gateway endpoint docs list the limits on reaching them from outside the VPC).
A worked cost comparison
Unit prices as of 2026-10 for us-east-1, quoted from the PrivateLink pricing and VPC pricing pages (check them, prices and regions differ): NAT gateway $0.045 per hour and $0.045 per GB processed; interface endpoint $0.01 per hour per AZ and $0.01 per GB for the first tier of data; gateway endpoint $0.
Take a private subnet that moves 1,000 GB a month to S3 and needs the NAT gateway for other traffic anyway:
| Path | Hourly part | Per-GB part | Monthly total |
|---|---|---|---|
| Via NAT gateway (S3 traffic only) | Already paid for other traffic | 1,000 x $0.045 = $45.00 | $45.00 extra |
| Via S3 gateway endpoint | $0 | $0 | $0.00 |
| Via an interface endpoint, 3 AZs | 3 x 730 h x $0.01 = $21.90 | 1,000 x $0.01 = $10.00 | $31.90 |
(730 is the usual hours-per-month approximation: 8,760 hours in a year divided by 12.) The gateway endpoint wins for S3 and DynamoDB whenever the traffic goes through NAT today. An interface endpoint pays for itself only when the per-GB saving beats the fixed hourly cost: at these prices the break-even is where 21.90 + 0.01 x GB = 0.045 x GB, so about 626 GB a month. Cross-AZ data transfer adds on top if the instance and the ENI are in different AZs.
Deep dive
Endpoint policies and locking a bucket to your VPC
An endpoint carries an endpoint policy, an IAM-style resource policy that limits which principals and actions may use that endpoint. The default allows everything (AWS endpoint policies). It is an extra filter, evaluated together with the caller's IAM policy and the service's own resource policy; all must allow.
The other direction is a bucket policy that denies any request that did not come through your endpoint, using the aws:SourceVpce condition key (S3 bucket policy examples). Together they give "the bucket is reachable only from this VPC, and the VPC can reach only these buckets". The sharp edge is that the deny also blocks you, from a laptop or the console, which is why teams keep a break-glass role excluded from the condition.
PrivateLink for your own service
To publish an internal service to another VPC or account, put it behind a Network Load Balancer (or Gateway Load Balancer), create an endpoint service on it, and let consumers create an interface endpoint to it (PrivateLink concepts). Properties worth stating:
- One-way. Connections are initiated from the consumer's ENI to the provider's NLB. The provider cannot open connections into the consumer VPC.
- No network merge. Consumers see one IP and one port, not your subnets. CIDRs may overlap, which peering forbids, so this is the standard answer when two companies both used
10.0.0.0/16. - Per-AZ. The consumer gets one ENI per chosen subnet; keep the endpoint in the same AZs as the clients so traffic does not cross AZs.
DNS resolution order and hybrid DNS
Inside the VPC the resolver checks, roughly, private hosted zones associated with the VPC, then forwarding rules, then public DNS (AWS DNS in your VPC). A private hosted zone only answers for VPCs it is associated with; forgetting the association is the usual reason "the private name resolves in one VPC but not the other".
On-premises machines cannot query 169.254.169.253 or the base-plus-2 address from outside the VPC. For hybrid setups, Route 53 Resolver provides an inbound endpoint (on-premises resolvers forward AWS-hosted names to ENIs in your VPC) and an outbound endpoint with forwarding rules (instances forward corporate names to on-premises resolvers) (Route 53 Resolver). Forward the same zone both ways and you create a loop, so each zone is forwarded in exactly one direction.
GCP: Private Google Access versus Private Service Connect
Private Google Access lets VMs with only internal IPs reach Google APIs. It is switched on per subnet, and traffic still goes to Google public IPs, over Google's network (Private Google Access). The special names private.googleapis.com (199.36.153.8/30) and restricted.googleapis.com (199.36.153.4/30) resolve to fixed virtual IP ranges that are only routable from inside, so you can reach them from on-premises over a hybrid link (configure Private Google Access).
Private Service Connect (PSC) is the PrivateLink analogue: a consumer endpoint is an internal IP address in your VPC (backed by a forwarding rule) that targets either Google APIs or a producer's service attachment (Private Service Connect). Choose Private Google Access for "my private VMs call Google APIs"; choose PSC when you want a stable IP you control, per-endpoint policy, or a third-party producer.
Azure: service endpoint versus private endpoint
A service endpoint extends your subnet's identity to a service such as Storage. The service firewall can then allow that subnet, but the service keeps its public IP and traffic is still addressed to it (service endpoints overview). A private endpoint is a network interface with a private IP in your subnet mapped to one specific resource, and DNS is changed so the resource name resolves to it, typically through a privatelink. private DNS zone (Private Endpoint overview, Private Endpoint DNS). The private endpoint is the Azure analogue of an AWS interface endpoint, and the service endpoint is closer to AWS gateway endpoints or GCP Private Google Access.
Textbook vs real world
| The textbook says | Production does | Why |
|---|---|---|
| Cloud services live on the public internet, so a private host needs NAT or a proxy to reach them | Private subnets reach S3, SQS and SaaS over endpoints, often with no internet gateway in the VPC at all | Providers expose service front ends on private IPs and routes, which cuts the NAT bill and the exposure |
| DNS gives one global answer per name | The VPC resolver gives a different answer for the same name inside the VPC (split-horizon) | It is how an endpoint redirects traffic without changing application code |
| To reach a service in another network, peer the networks | Expose just that service with PrivateLink, Private Service Connect or Private Link | Peering merges routing domains and forbids overlapping CIDRs. An endpoint exposes one service, one way |
| Private means unauthenticated | Endpoints keep IAM, resource policies and security groups in force | A network path is not an authorization decision |
In production
- SaaS vendors sell private connectivity. Snowflake documents AWS PrivateLink for its accounts, Datadog documents sending telemetry over PrivateLink, and MongoDB Atlas documents private endpoints. Each publishes an endpoint service that you consume with an interface endpoint in your VPC.
- Compliance-driven "no internet gateway" VPCs. Workloads with no internet route reach AWS APIs only through endpoints, and endpoint policies plus
aws:SourceVpcebucket policies make the allowed destinations explicit. - Private Kubernetes clusters. AWS documents the endpoints a cluster with no internet access needs, including ECR, S3 and CloudWatch Logs (Amazon EKS private clusters). Image pulls are the usual high-volume item, which is why the gateway endpoint for S3 matters.
- The NAT bill. The first thing to check on a surprising NAT line item is how much of it is S3 or DynamoDB traffic; the cost table above shows what moving it to a gateway endpoint saves.
History and evolution
- 2015 Private subnets reach S3 only through NAT or a public IP. AWS adds the S3 gateway endpoint, a route-table-based private path.
- 2017 Route entries cannot cover most AWS APIs, which have no stable IP range suited to a prefix list. AWS PrivateLink introduces interface endpoints, an ENI plus DNS override, and DynamoDB gains a gateway endpoint.
- 2018 ISVs want to serve customers without peering or shared CIDRs. Endpoint services behind an NLB make provider-side publication a normal pattern.
- Around 2019 to 2021 Other clouds follow with the same ENI-plus-DNS idea: Azure Private Link and Private Endpoint, and Google Private Service Connect.
- Now Private-by-default service access is a baseline for regulated workloads. Check each provider's service list for current coverage rather than a frozen figure.
- Next More services offer private front ends directly, and gateway-style endpoints are joined by interface equivalents (S3 already has both).
The years above are from memory of the provider announcements; confirm them in each provider's release notes before quoting them in an interview.
Hands-on
Create both endpoint types with the AWS CLI. The IDs are placeholders:
See which public ranges the gateway route represents, and ask the VPC resolver directly:
Look for the connected-to address: a 10.x address means the endpoint path, a public address means private DNS is off or the endpoint is missing. A curl that hangs on connect points at the endpoint's security group missing inbound 443 from your subnet. For a gateway endpoint, check the route instead: aws ec2 describe-route-tables should show a DestinationPrefixListId row with a vpce- target. dig and nslookup exist on macOS and Linux. Output above is abbreviated and the addresses are examples.
Gotchas
Interview questions
Show answer
Create an S3 gateway endpoint and associate it with the subnet's route table. AWS adds a route sending the S3 prefix list to the endpoint, which wins over the default route by longest-prefix match. It needs no ENI, no security group and costs nothing.
Follow-ups:
- Gateway versus interface endpoint? Gateway is a free route, VPC-only, S3 and DynamoDB. Interface is an ENI with private DNS, billed per hour and GB, and reachable from on-premises.
- Cost? The gateway endpoint is free. NAT would bill about $0.045 per GB for the same traffic (us-east-1, as of 2026-10).
Show answer
Peering joins two networks so any allowed address can reach any other, and it forbids overlapping CIDRs. PrivateLink exposes one service to the consumer through an ENI, one way from consumer to provider. Pick PrivateLink for "a customer needs this API, not my network".
Follow-ups:
- Overlapping CIDRs? PrivateLink works, because nothing is routed between the VPCs; peering cannot be created.
- Many consumers? PrivateLink scales per endpoint, peering grows toward a mesh. See private connectivity.
Show answer
Work out which kind it is. For a gateway endpoint, the route table of that subnet probably is not associated with the endpoint, so the prefix-list route is missing. For an interface endpoint, private DNS is likely off or the VPC lacks enableDnsSupport and enableDnsHostnames, so the name still resolves to a public IP.
Follow-ups:
- How do you prove the path?
digthe service name from the instance: a private IP means the interface endpoint. For a gateway endpoint, inspect the route table for thevpce-row and the VPC flow logs for the destination. - Why would a non-AWS client still go public? Its resolver never sees your private zone.
Show answer
Put the service behind an NLB, create an endpoint service on it, and let the customer create an interface endpoint to it, optionally with manual acceptance. The customer sees one private IP, you see connections from their endpoint, and neither network is routed into the other.
Follow-ups:
- Consumer-side cost? They pay the hourly per-AZ endpoint fee and the per-GB charge.
- AZ alignment? Enable the endpoint service in the AZs the consumers use, so traffic does not cross AZs.
Show answer
Create a Route 53 Resolver inbound endpoint in the VPC and configure the on-premises DNS servers to forward that zone to its ENI addresses over VPN or Direct Connect. For the reverse direction, add an outbound endpoint and a forwarding rule to your corporate resolvers.
Follow-ups:
- Loops? Forward each zone in one direction only, or queries bounce between resolvers.
- Why not query the base-plus-2 resolver directly? It is only reachable from inside the VPC.
Show answer
Use a bucket policy that denies requests unless aws:SourceVpce equals your endpoint ID, and add an endpoint policy that limits which buckets and actions the endpoint allows. Requests then must come through the endpoint and the endpoint cannot reach other buckets.
Follow-ups:
- Break-glass? Exclude a specific admin role from the deny, or you lock yourself out of the console.
- Why
SourceVpcerather than a source IP? Through an endpoint the source is a private address, so conditions on public IPs do not apply.
Show answer
It means the same name gets different answers depending on where the question comes from. The VPC resolver answers sqs.us-east-1.amazonaws.com with a private endpoint IP inside the VPC, while the internet gets the public one. It lets endpoints redirect traffic without changing application code. See DNS.
Follow-ups:
- Where does the private answer come from? A private hosted zone associated with the VPC.
- What breaks it? A VPC without the association, or without
enableDnsSupport.
Fun facts
- Gateway endpoints cost nothing, and only S3 and DynamoDB support the gateway type.
- S3 is unusual in having both a gateway and an interface endpoint.
- The AWS resolver is reachable at two addresses,
169.254.169.253and the VPC base plus 2. - Google's
private.googleapis.comname resolves to199.36.153.8/30, a fixed range that only works from inside a Google Cloud VPC or a connected network.
Cheat sheet
- S3 or DynamoDB, inside the VPC: gateway endpoint (free).
- Any other AWS API, a SaaS vendor, your own service, or access from on-premises: interface endpoint (PrivateLink).
- GCP: Private Google Access for Google APIs, or Private Service Connect when you need a controlled IP.
- Azure: private endpoint when you need a private IP, service endpoint for a cheap subnet allow-list.