At PostNL we are building most of our applications with
Now when you'd like to add your own custom DNS on a public API Gateway you can do so by creating a custom domain name and using Route 53 to point to the API Gateway endpoint (you can leverage the
At this point it still looks simple, but when you'd like to have a private API Gateway you can't use a custom domain name and you can't use Route 53 to point to the API Gateway endpoint. This is where it gets tricky.
Why a custom domain?
Even though it's not supported for Private API's you might wonder why would you need a custom domain on your API Gateway. To me there is a simple reason why I want this. Within a larger organization on AWS you often have other teams / aws accounts invoke your api's.
When you are in a situation like this often you have 2 options:
- There is a central team that manages all the api's and they provide you with the endpoint to invoke the api. (which still means that you need to provide a private network connection to the central API team).
- You allow another team to invoke your api's by providing them with the endpoint of the api gateway.
When you don't have custom dns on your API Gateway the only option to provide the API to a different account is to provide them with the API Gateway ID, which they'll use together with a VPC Endpoint in their account to reach your API Gateway. This is not a very user-friendly way to provide an API to another team.
CDK Example
It's not a post from me without a CDK example, so here it is. In this example we are creating an API Gateway with a simple Mock Integration Response that is reachable via private DNS. The API Gateway is deployed in a VPC and is only reachable when invoked via the VPC Endpoint, to be able to use private DNS we are deploying an Application Load Balancer which is pointed towards the VPC Endpoint. Based upon the domain name that is pointed towards the Application Load Balancer and that is configured on the API Gateway we can reach the API Gateway via the private DNS.
const apiFqn = "api.cino.dev";
// Step 1: Retrieve vpc / hosted zones
const [vpc, publicHostedZone, privateHostedZone] = this.getNetwork();
// Step 2: Create API Gateway VPC Endpoint
const apiGatewayVpcEndpoint = this.createApiGatewayVpcEndpoint(vpc);
// Step 3: Create certificate for the API Gateway / ALB
const acmCertificate = this.createCertificate(apiFqn, publicHostedZone);
// Step 3: Create ALB
const alb = this.createApplicationLoadBalancer(vpc, apiGatewayVpcEndpoint);
// Step 4: Create API Gateway
this.createApiGateway(apiFqn, acmCertificate, apiGatewayVpcEndpoint);
// Step 5: Create ALB Listener for API Gateway VPC Endpoint
this.createApiGatewayVpcEndpointListener(
acmCertificate,
vpc,
alb,
apiGatewayVpcEndpoint
);
// Step 6 Create Route53 records pointing towards
// the Application Load Balancer
this.createDnsRecords(privateHostedZone, alb, apiFqn);
As you see we need the following resources:
- VPC
- Hosted Zones (Public & Private)
- Public Hosted Zone is used for the certificate
- Private Hosted Zone is used for the DNS records
- API Gateway VPC Endpoint
- Certificate for the API Gateway / ALB
- Application Load Balancer
- Listener on port 443 for your domain pointing towards the VPC Endpoint Private IP Adresses
- API Gateway
- Custom Domain Name pointing towards the Application Load Balancer
For the full example you can visit the .
Conclusion
In this post I've shown you how you can create a private API Gateway with DNS. This is not a straightforward process and requires some additional resources to make it work. However, when you have a need for a private API Gateway with DNS this is the way to go.
Please have a good look at the Github link provided as there are a lot more details to be found and it is a fully working example with a simple cdk deploy command. (when you provide your own route53 / hosted zone)
I hope this post was helpful to you and if you have any questions or remarks feel free to reach out to me on .
SOCIAL SHARE CARD GENERATOR