Access Edge-optimized, Regional and Private API Gateway endpoints from the same VPC
Accessing Edge-optimized, Regional, and Private API endpoints from the same VPC presents challenges. This blog details why this occurs and offers solutions, including using custom domain names or special URLs.
Providing simultaneous access to Edge-optimized, Regional and Private API endpoints from the same VPC simultaneously is not straightforward. This post explains why and how to fix it.
API Gateway provides 3 endpoint types (ways to expose an API):
1- Regional API endpoint
The hostname of an API deployed to the specified AWS Region and intended to serve clients, such as EC2 instances, in the same AWS Region. API requests are targeted directly to the Region-specific API Gateway API without going through any CloudFront distribution.
2- Edge-optimized API endpoint
The hostname of an API Gateway API deployed to the specified AWS Region while using a CloudFront distribution to facilitate client access typically from across AWS Regions. API requests are routed to the nearest CloudFront Point of Presence (POP), which typically improves connection time for geographically dispersed clients.
3- Private API endpoint
An API endpoint that is exposed through interface VPC endpoints and allows a client to securely access private API resources from inside a VPC. Private APIs are isolated from the public Internet, and they can only be accessed using VPC endpoints for API Gateway (after allowing access using resource policies and security groups).
Description of the issue
You can create private REST APIs that can only be accessed from within VPCs using an interface VPC endpoint. Traffic to your private API uses secure connections and does not leave the Amazon network, hence its name.
Using API Gateway resource policies, you can allow or deny access to your API from selected VPCs and VPC endpoints (including across AWS accounts). Each VPC endpoint can be used to access multiple private APIs.
One of the settings of VPC Endpoints is "Enable Private DNS Name." This setting is enabled by default. When private DNS is enabled, you can access your API via private or public DNS. (This setting doesn't affect who can access your API, only which DNS addresses they can use.) However, you cannot access public API Gateway APIs from a VPC by using an API Gateway VPC endpoint with private DNS enabled (unless you implement any of the workarounds below).
Applications running in the VPC trying to access a non-private regional API Gateway endpoint will get an HTTP 403 Forbidden error when private DNS is enabled for an API Gateway interface VPC endpoint that's associated with the VPC. All requests (including requests to API Gateway public APIs) from the VPC to API Gateway APIs resolve to that interface VPC endpoint. It's not possible to connect to public APIs using a VPC endpoint for API Gateway.
The root cause of the issue is this: When a DNS query is resolved for a public API (in the same region) from inside a VPC, the resolved DNS points to the private IP of the associated VPC endpoint instead of the public IP address of the public API. The API call is then routed to the public API through the VPC endpoint instead of routing it through the Internet. Because VPC endpoints can route traffic only to private APIs, the result is an HTTP 403 error.
Workarounds
The workarounds to enable access to both private and public API Gateway APIs from the same VPCs (and same region) depend on whether we set the "Enable Private DNS Name" attribute of the VPC Endpoint or not.
If the "Enable Private DNS Name" attribute is set
You can use the default DNS name of the API Gateway Private API. You must use an edge-optimized custom domain name or regional custom domain name to access your public API(s). Unfortunately, setting custom domain names for a public API is not always possible, as the public API might not be under our control. Resources in your VPC that try to connect to public APIs must have internet connectivity.
If the "Enable Private DNS Name" attribute is unset
To access the private API Gateway API, you should use a special URL built using a unique pattern as documented here (Accessing your private API using a Route53 alias): https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-api-test-invoke-url.html#apigateway-private-api-route53-alias
Your Private API URL will look like this: https://{rest-api-id}-{vpce-id}.execute-api.{region}.amazonaws.com/{stage}.
When you associate a VPC endpoint with your private API, API Gateway generates a new Route 53 ALIAS DNS record. You can use this record to invoke your private APIs just as you do your edge-optimized or Regional APIs without overriding a Host
header or passing an x-apigw-api-id
header.
You can access any other public API Gateway APIs (or any other APIs and services in general) using the VPC's route to the Internet. Resources in your VPC that try to connect to public APIs must have internet connectivity.