
Serverless Private APIs — Part 2 🚀
How to allow private serverless platform APIs to communicate securely internally using custom domain names within your organisations, without needing to traverse the public internet. Including visuals and code repository written in TypeScript and the AWS CDK.

Introduction
In part one of this article, we discussed how we can use Amazon API Gateway Private APIs alongside VPC Endpoints to have two VPCs (even across different AWS accounts) communicate internally without the traffic traversing the public internet. We found that there are some limitations with this approach, such as not being able to add custom domain names for Private APIs. Ideally what we would like is:

💡 Note: In reality not all calls would be synchronous like this, and most architectures should be event-driven first in my opinion. That being said, even in event-driven serverless architectures there is almost always a need for synchronous API calls. For more information on serverless event-driven systems check out the following:
In this scenario we have some well defined internal custom domains which are only accessible via our VPCs (not publicly accessible on the internet as they need to be secure), and they are accessed only by the APIs which back the mobile and web front ends.
This article discusses how we can work around this limitation with private APIs on API Gateway and custom domain names through using a particular architectural approach. (see part one link below)
The Github repo for the second part of this article can be found here.
Lets recap 💭
In the first article we built out the following simple architecture as discussed above:

This approach may be fine for certain simple use cases, and keeps all of your traffic private and secure on the AWS internal network; however has the following limitations:
- You are unable to use custom domain names. This means that you will not be able to have an internal private API with a name such as ‘
stock.internal.acme.co.uk
’. Instead you need to utilise an auto generated URL which is not very pretty to look at ‘https://{rest-api-id}-{vpce-id}.execute-api.{region}.amazonaws.com/{stage}’
- Auto generated URLs. The auto generated URLs would change name each time there is a need to recreate the stack, meaning all consumers would need to change their targets of course i.e. based on ‘
https://{rest-api-id}-{vpce-id}.execute-api.{region}.amazonaws.com/{stage}’
- Use of VPC Endpoints. The consuming VPC needs to use VPC Endpoints to communicate with the private API in the other VPC. This is not ideal when you have many products and teams within an organisation. For smaller teams and organisations this may be fine.
- DNS Issues. There are various DNS issues that can be worked around as discussed, but not ideal.
What services are we going to use? 🧰
We are going to be using the following AWS services, over and above what we used in part one of the article:
Feel free to skip to the next section ‘What are we building?’ if you are comfortable with the majority of the AWS services and just want to see the architecture pattern.
Route 53 Private Hosted Zones ✔️
A private hosted zone is a container that holds information about how you want Amazon Route 53 to respond to DNS queries for a domain and its subdomains within one or more VPCs that you create with the Amazon VPC service. For a deeper dive into DNS and Route 53 on AWS see the following YouTube video below:
Application Load Balancers ✔️
Elastic Load Balancing automatically distributes your incoming traffic across multiple targets, such as EC2 instances, containers, and IP addresses, in one or more Availability Zones. It monitors the health of its registered targets, and routes traffic only to the healthy targets. Elastic Load Balancing scales your load balancer as your incoming traffic changes over time. It can automatically scale to the vast majority of workloads. For a deeper dive into ALB’s on AWS see the following YouTube video below:
Certificate Manager ✔️
AWS Certificate Manager is a service that lets you easily provision, manage, and deploy public and private Secure Sockets Layer/Transport Layer Security (SSL/TLS) certificates for use with AWS services and your internal connected resources. SSL/TLS certificates are used to secure network communications and establish the identity of websites over the Internet as well as resources on private networks. For a deeper dive into certificates on AWS see the following YouTube video below:
What are we building? 🏗️
💡 Note: To run the examples you will need two separate AWS Accounts or two VPCs in one account. I also won’t be covering VPC Peering in this article (this will be in Part 3).
The diagram below shows what we are building in this part of the article (2), allowing our domain services to communicate through Private API Gateways with custom domain names internally i.e. the Orders domain service can call the internal Stock domain service without traversing the public internet:

Lets talk through the diagram and associated code
1.) In AWS account one we have a public facing Orders
API, which for ease of the demo has no authentication.
💡 Note: Ideally this would be tied down using Amazon Cognito for example.
2.) The Orders
API targets Lambdas in two separate private subnets/AZ’s, which subsequently make a call across to an internal Stock platform domain service API using the domain name https://stock.{your domain}.co.uk/prod/stock
.(note it is also using an API Key and Usage Plan)
3.) We use VPC Peering and sharing Route 53 Private Zones across VPCs in separate AWS accounts, so they can communicate with each other internally on the AWS network. This is basically a dedicated communication path between the two private subnets across AWS accounts, as well as shared internal custom DNS.
💡 Note: We will cover the setting up of VPC Peering and Route 53 Private Zone Associations in part 3 of this article so we can continue this journey.
4.) There is an A record in the Private Hosted Zone which targets an internal Application Load Balancer in the second AWS account.
5.) The ALB has a custom SSL cert associated with it for our internal domain name which must also match the same SSL cert on the private Stock API gateway.
💡 Note: We won’t cover here how to generate a custom certificate, and I would imagine you already have some in your AWS accounts to play around with.
6.) The ALB routes traffic to our VPC Endpoint using IP address(s) which is deployed across two AZs.
7.) The VPC Endpoint routes traffic to the Private Stock
API Gateway, which has a resource policy on it stating the only traffic allowed through to it is via the internal application load balancer. We also add a Resource Policy on the Private API stating that only traffic from the VPC Endpoint is allowed. This keeps the full chain secure.
💡 Note: You can further tie this down using VPC Endpoint policies and security groups depending on your needs.
8.) The Private Stock
API Gateway then calls Lambdas in its own VPC to return stock data. As you can see below this is stubbed for this example.
Deploying the solution! 👨💻
🛑 Note: Running the following commands will incur charges on your AWS accounts.
Let’s deploy the basic code example which you can clone here: https://github.com/leegilmorecode/serverless-private-apis-part-2
💡 Note: for my example the deploy NPM scripts are using different AWS profiles as we are deploying to two separate AWS accounts i.e. that is why they are not two separate CDK stacks in the same app (my profiles are called default and beta).
- Run the following command in both the order-service and stock-service folders:
npm i
- Change directory into the orders service folder and run
npm run deploy
- Change directory into the stock service folder and run
npm run deploy
At this point you would need to setup a VPC Peering Connection between both VPCs manually, details of which can be found here. I will be covering this in Part 3 of this article through the CDK rather than doing this manually, as well as what the differences are between this and AWS Transit Gateway. (see below an example of VPC Peering)

A VPC peering connection is a networking connection between two VPCs that enables you to route traffic between them using private IPv4 addresses or IPv6 addresses. Instances in either VPC can communicate with each other as if they are within the same network.
You would then need to associate your Private Hosted Zone with both AWS accounts, with the basic steps being defined here. I will be covering this further in Part 3 of this article, but this basically allows us to run DNS queries for stock.yourdomain.co.uk
in the Orders domain VPC, allowing it to find and route traffic internally.
💡 Note: this is the minimal code and architecture to allow us to discuss key architecture points in the article, so this is not production ready and does not adhere to coding best practices. (For example no authentication on end points). I have also tried not to split out the code too much so example files are easy to view with all dependencies in one file.
Testing the solution 🎯
Once you have deployed the solution you can use the postman file in serverless-private-apis/postman/serverless-private-apis.postman_collection.json
to try hitting the orders public endpoint, which in itself will call the internal Stock API privately on the AWS network:

Summary
I hope you found that useful! Hopefully this has given you an easy way to use private APIs and custom domain names within your organisation. Is there a more effective approach for this? If so, please reach out!
Go and subscribe to my Enterprise Serverless Newsletter here for more of the same content:
Wrapping up 👋
Please go and subscribe on my YouTube channel for similar content!

I would love to connect with you also on any of the following:
https://www.linkedin.com/in/lee-james-gilmore/
https://twitter.com/LeeJamesGilmore
If you found the articles inspiring or useful please feel free to support me with a virtual coffee https://www.buymeacoffee.com/leegilmore and either way lets connect and chat! ☕️
If you enjoyed the posts please follow my profile Lee James Gilmore for further posts/series, and don’t forget to connect and say Hi 👋
Please also use the ‘clap’ feature at the bottom of the post if you enjoyed it! (You can clap more than once!!)
This article is sponsored by Sedai.io

About me
“Hi, I’m Lee, an AWS Community Builder, Blogger, AWS certified cloud architect and Principal Software Engineer based in the UK; currently working as a Technical Cloud Architect and Principal Serverless Developer, having worked primarily in full-stack JavaScript on AWS for the past 5 years.
I consider myself a serverless advocate with a love of all things AWS, innovation, software architecture and technology.”
*** The information provided are my own personal views and I accept no responsibility on the use of the information. ***
You may also be interested in the following: