Containers
Building HTTP API-based services using Amazon API Gateway, AWS PrivateLink and AWS Fargate
Authors: Irshad A. Buchh, Sr. Partner Management Solutions Architect at AWS & Andy Warzon, CTO at Trek10
This post is contributed by Amazon Web Services and Trek10. As an AWS Partner Network (APN) Premier Technology Partner with AWS Competencies in DevOps, IoT, and SaaS Consulting, Trek10 provides consulting and managed services for AWS clients of all sizes, continuously engaging in work with all types of industries and companies ranging from startups to Fortune 100 enterprises.
Introduction
Prior to the availability of AWS PrivateLink, services residing in a single Amazon VPC were connected to multiple Amazon VPCs either (1) through public IP addresses using each VPC’s internet gateway or (2) by private IP addresses using VPC peering.
With AWS PrivateLink, service connectivity over Transmission Control Protocol (TCP) can be established from the service provider’s VPC (producer) to the service consumer’s VPC (consumer) in a secure and scalable manner. Tom Adamski has provided an architecture where he shows one way of using AWS PrivateLink along with ALB and NLBs to publish internet applications at scale. Mani Chandrasekaran provided a solution where he uses API Gateway to expose applications running on AWS Fargate using REST APIs, but it uses NLB since ALB is not yet supported by this architecture.
Our solution leverages the existing applications/APIs running in AWS Fargate behind a Private ALB inside a VPC and proposes an architecture to expose these APIs securely through HTTP APIs using Amazon API Gateway and AWS PrivateLink.
The target audience for this post is developers and architects who want to architect API based services using the existing applications running inside Amazon VPCs.
Overview of concepts
- AWS PrivateLink: AWS PrivateLink provides secure, private connectivity between Amazon VPCs, AWS services, and on-premises applications on the Amazon network. As a result, customers can simply and securely access services on AWS using Amazon’s private network, powering connectivity to AWS services through interface Amazon VPC endpoints. AWS PrivateLink provides three main benefits: uses private IP addresses for traffic, simplifies network management, and facilitates your cloud migration
- HTTP API: HTTP API is a new flavor of API Gateway and it focuses on delivering enhanced features, improved performance, and an easier developer experience for customers building with API Gateway. To create an HTTP API, you must have at least one route, integration, stage, and a deployment.
- AWS Fargate: AWS Fargate makes it easy for you to focus on building your applications. Fargate removes the need to provision and manage servers, lets you specify and pay for resources per application, and improves security through application isolation by design. Fargate works with both Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS).
Prerequisites
In order to implement the instructions laid out in this post, you will need the following:
- An AWS account
Architecture
We shall be using AWS Cloud Development Kit (CDK) in TypeScript in this blog post. We shall create one AWS CDK application consisting of two AWS CDK stacks FargateVpclinkStack and HttpApiStack. Inside the FargateVpclinkStack, we deploy two Node.js microservices (book-service and author-service) using AWS Fargate within the Producer VPC. An internal load balancer distributes external incoming application traffic across these two microservices. In order to implement the private integration, we create a Vpclink to encapsulate connections between API Gateway and these microservices. Inside the HttpApiStack, we create an HTTP API that integrates with the Amazon Fargate microservices running inside the FargateVpclinkStack using the Vpclink and internal load balancer listener.
Here are the steps we’ll be following to implement the above architecture:
- Create and configure AWS Cloud9 environment
- Build two sample microservices
- Examine the CDK code
- Provision AWS resources using the CDK
- Test the HTTP API
- Cleanup
- Conclusion
Create and configure AWS Cloud9 environment
You can use a local development machine to set up an environment or use AWS Cloud9. However in this blog post we shall use AWS Cloud9, follow the instructions here to create an AWS Cloud9 environment.
Build two sample microservices
1. Clone the GitHub repository
Open a new terminal inside AWS Cloud9 IDE and run:
a) Build and test book-service locally
Replace XXXXXXXXXXX with your AWS account id and using terminal inside AWS Cloud9 IDE run:
Click “Preview/Preview Running Application” and append api/books/health to the end of the url so that url looks like “https://XXXXXXXXXXXXXXXXXXX.vfs.cloud9.us-west-2.amazonaws.com/api/books/health.” Observe the response from the running book-service service.
Open a new terminal inside AWS Cloud9 IDE and run the following curl command:
Observe the response from the running book-service service.
In order to avoid the port conflict later on, kill the book-service container by running:
Get the ‘CONTAINER ID’ from the previous command and then run:
b) Build and test author-service locally
Replace XXXXXXXXXXX with your AWS account id and using terminal inside AWS Cloud9 IDE run:
Click “Preview/Preview Running Application” and append api/authors/health to the end of the url so that url looks like “https://XXXXXXXXXXXXXXXXXXX.vfs.cloud9.us-west-2.amazonaws.com/api/authors/health.” Observe the response from the running author-service service.
Open a new terminal inside AWS Cloud9 IDE and run the following curl command:
curl -s http://localhost:8080/api/authors | jq
Observe the response from the running author-service service.
2. Create Amazon ECR repositories
Amazon Elastic Container Registry (ECR) is a fully managed container registry that makes it easy to store, manage, share, and deploy container images containing the business logic of the microservices. Amazon ECR repositories host your container images in a highly available and scalable architecture, allowing you to deploy containers reliably for your applications. Each AWS account is provided with a single (default) Amazon ECR registry.
Replace XXXXXXXXXXX with your AWS account id and using terminal inside AWS Cloud9 IDE run:
3. Push images to Amazon ECR
Replace XXXXXXXXXXX with your AWS account id and using terminal inside AWS Cloud9 IDE run:
Examine the CDK code
We shall implement this architecture using an AWS CDK application comprising of two individual CDK stacks:
- FargateVpclinkStack — contains the Fargate services and Vpclink.
- HttpApiStack — contains the HTTP API integrated with Fargate services using Vpclink.
Let us discuss these stacks one by one.
FargateVpclinkStack

Under the cdk/singleAccount/lib folder, open the fargate-vpclink-stack.ts file and let us explore the CDK variables and the various CDK constructs.
Export Vpclink and ALB Listener:
These two variables enable us to export the provisioned Vpclink along with the ALB Listener from FargateVpclinkStack stack so as to use these to create the HTTP API in the HttpApiStack stack.
VPC:
This single line of code creates a ProducerVPC with two Public and two Private Subnets.
ECS cluster:
This creates an Amazon ECS cluster inside the ProducerVPC, we shall be running the two microservices inside this ECS cluster using AWS Fargate.
Cloud Map namespace:
AWS Cloud Map allows us to register any application resources, such as microservices, and other cloud resources, with custom names. Using AWS Cloud Map, we can define custom names for our application microservices, and it maintains the updated location of these dynamically changing microservices.
ECS task role:
We need to specify an IAM role that can be used by the containers in a task.
Task definitions:
A task definition is required to run Docker containers in Amazon ECS, we shall create the task definitions (bookServiceTaskDefinition and authorServiceTaskDefinition) for the two microservices.
Log groups:
Let us create two log groups bookServiceLogGroup and authorServiceLogGroup and the two associated log drivers.
ECR repositories:
Let us import the two repositories book-service and author-service that we created earlier using AWS CLI.
Task containers:
We shall define a single container in each task definition.
Security groups:
In order to control the inbound and outbound traffic to Fargate tasks, we shall create two security groups that act as a virtual firewall.
Fargate services:
Let us create two ECS/Fargate services (bookService & authorService) based on the task definitions created above. An Amazon ECS service enables you to run and maintain a specified number of instances of a task definition simultaneously in an Amazon ECS cluster. If any of your tasks should fail or stop for any reason, the Amazon ECS service scheduler launches another instance of your task definition to replace it in order to maintain the desired number of tasks in the service.
ALB:
The load balancer distributes incoming application traffic across multiple ECS services, in multiple Availability Zones. This increases the availability of your application. Let’s add an Application Load Balancer.
ALB listener:
An ALB listener checks for connection requests from clients, using the protocol and port that we configure.
Target groups:
We shall create two target groups, bookServiceTargetGroup for bookService microservice and authorServiceTargetGroup for authorService microservice.
Vpclink:
It is easy to expose our HTTP/HTTPS resources behind an Amazon VPC for access by clients outside of the Producer VPC using the API Gateway private integration. To extend access to our private VPC resources beyond the VPC boundaries, we can create an HTTP API with a private integration for open access or controlled access. The private integration uses an API Gateway resource of VpcLink to encapsulate connections between API Gateway and targeted VPC resources. As an owner of a VPC resource, we are responsible for creating an Application Load Balancer in our Producer VPC and adding a VPC resource as a target of an Application Load Balancer’s listener. As an HTTP API developer, to set up an HTTP API with the private integration, we are responsible for creating a VpcLink targeting the specified Application Load Balancer and then treating the VpcLink as an effective integration endpoint. Let’s create a Vpclink based on the private subnets of the ProducerVPC.
HttpApiStack
Now let us create an HTTP API based on the Fargate services created in FargateVpclinkStack.
Under the ~/environment/http-api-aws-fargate-cdk/cdk/singleAccount/lib folder, open the httpApi-stack.ts file and let us explore the following different CDK constructs.
Consumer VPC:
This single line of code creates a ConsumerVPC with two public subnets.
EC2 instance:
HTTP API:
Let’s create an HTTP API based on a default stage.
API integration:
The following construct will integrate the HTTP API with the backend microservices using the Vpclink and the Application Loadbalancer Listener.
API route:
Now let’s create the HTTP API proxy routes using the API integration.
Provision AWS resources using the CDK
Install AWS CDK
The AWS Cloud Development Kit (AWS CDK) is an open-source software development framework to model and provision your cloud application resources using familiar programming languages. If you would like to familiarize yourself the CDKWorkshop is a great place to start.
Using Cloud9 terminal use the following commands:
Take a note of the latest version that you install, at the time of writing this post it is 1.79.0. Open the package.json file in ~/environment/http-api-aws-fargate-cdk/cdk/singleaccount and replace the version “1.79.0” of the following modules with the latest version that you have installed above.
Using Cloud9 terminal use the following commands:
This will install all the latest CDK modules under the node_modules directory.
Let us now create an ssh key pair using AWS CLI:
Let us now provision the CDK application. Using Cloud9 terminal use the following commands:
At the prompt, enter y and CDK CLI shall deploy the FargateVpclinkStack and will create 54 resources.
At the second prompt, enter y and CDK CLI shall deploy the HttpApiStack and will create 21 resources.
Test the HTTP API
Take a note of the EC2 IP address along with the HTTP API endpoints of the Book Service and Author Service. Using the Cloud9 terminal run the following commands:
Here is the integration of the HTTP API with the backend Lambda functions inside the AWS Management Console.
Cleanup
To clean up the resources created by the CDK, run the following commands in a terminal of your Cloud9 instance:
At the prompt, enter y.
To delete the ssh key pair, run the following command:
Log into the AWS Management Console and delete book-service and author-service repositories. Also delete the Cloud9 environment.
Conclusion
This post demonstrated how to architect HTTP API-based services using Amazon API Gateway based on existing microservices running behind a private Application Load Balancer inside private VPCs using AWS PrivateLink. The benefit of this serverless architecture is that it takes away the overhead of having to manage underlying servers and helps reduce costs, as you only pay for the time in which your code executes.