Tutorial

AWS API Gateway private integration with HTTP API and a VPC Link

Protecting your resources in a private subnet while using the API Gateway as a gatekeeper

Manu Rana
The Startup
Published in
6 min readJun 24, 2020

--

One of the best advice on AWS that I got was to deploy my app behind a Load Balancer (LB)and an API Gateway (APIG). Even if you are starting out with a single EC2, it will help in the long run if it is behind an APIG and an LB. The LB ensures that you can scale as and when you want, and the APIG gives you logging, throttling, and other goodies that you will need.

From my previous article on the subject,

A very typical deployment architecture for smaller startups is to have an API Gateway at the front, which passes on requests to an ELB, which in turn distributes them to a bunch of EC2 instances. ELBs and EC2s are typically inside a VPC. For an API Gateway to use an ELB as the HTTP endpoint for integration, the ELB needs to be exposed to the internet. This implies that an API request can theoretically be made directly to the ELB, bypassing all the rules configured on the API Gateway. This is a concern.

You can allow only requests originating from the API Gateway on your app by configuring client certificates, but that does not prevent flooding style DDOS attacks on the ELB (and the EC2s). An ideal solution is to create a link between the API Gateway and the ELB which is NOT exposed to the internet.

The article goes on to explain how to use a VPC Link to create such an architecture. If you go through it, you will find that it is a slightly cumbersome process, and you can only use Network Load Balancers (NLBs).

Very recently, AWS announced a new service called HTTP APIs for Amazon API Gateway. This is “a service built from the ground up to be faster, lower cost, and simpler to use”, in their words.

But more importantly, the new service makes it much easier to create the architecture described above and gives us an option to use an Application Load Balancer (ALB). Let us explore how to go about it. As before, the information is present piecemeal in a couple of AWS documentation pages, I am just bringing it together in one place.

We will take it in three steps: create the ALB, create a VPC Link, and create an HTTP API, in that order

A. Create the ALB

Follow the tutorial here, and use the wizard. The following are the key things to keep in mind. Refer to the screenshots at the end of the section.

  1. Create it as an INTERNAL facing ALB. We don’t want to expose it to the internet.
  2. There is only one listener on port 80 (This is the default). We will be terminating SSL on the APIG, so we don’t need a secure listener. You can safely ignore the warning you will get about this in Step 2 of the wizard.
  3. If you are adding PUBLIC subnets to the ALB as its while configuring Availability Zones, you might get a warning about it. It looks like you can safely ignore it.
  4. In Step 3 of the wizard, the Security Group that is created/assigned to the ALB can be fairly open for now (accept HTTP on TCP port 80 from anywhere). Later, we will modify it to only accept requests from the APIG via the VPC Link
  5. In Step 4 of the wizard, the Target Group should have a target type as INSTANCE. Assuming that your EC2 is handling requests on port 80, you can keep the rest of the parameters as default. In Step 5, you can register your EC2 instance.
  6. Configure the EC2 SG to accept traffic ONLY from the ALB, only on port 80. This is done from the EC2 console

B. Create a VPC Link

  1. From the EC2 console, create a new Security Group for the VPC Link. Again, this can be pretty open for now, with HTTP traffic on port 80 allowed from anywhere.
  2. While you are there, alter the ALB SG to accept traffic only from the VPC Link SG, only on port 80.
  3. From the API Gateway console, create a new VPC Link for HTTP APIs. Choose the subnets in both AZs as before (the same subnets that were chosen during the ALB creation). Assign the recently created SG to it. It should take about 2–3 minutes to be provisioned.

C. Create an HTTP API

From the API Gateway Console, create a new HTTP API using the wizard

  1. No need to add any integration in Step 1, we will do it later (private integrations can only set up after the creation of the API)
  2. Same with configuring routes in Step 2. Skip it, we will do it later. You cannot set up routes without defining integrations
  3. Use all default values in Step 3 for stages. Note that there is a default stage, and it configured for auto-deployment.
  4. Review and click on CREATE.

Your new API should be ready.

Let's create the route.

  1. Click on the API name to get to the details page for this new API (if not already there)
  2. Click on routes in the left nav bar and click on CREATE. Use default values of ANY for the method, and / for the route.

Now we will attach an integration to this route

  1. Click on the route on the left side of the screen, and click on the CREATE AND ATTACH INTEGRATION button on the right.
  2. Choose Private Resource, and then ALB/NLB
  3. Choose the ALB that we had configured earlier, with the default listener on port 80
  4. Lastly, choose the VPC Link that we had configured, and click CREATE.

And we are done!

At this point, you should be able to use the Invoke URL of the API to make a call to your EC2, which is now behind an APIG/ALB pair connected with a VPC Link

D. Further Steps

We can assign a custom domain to this new API, but this is out of the scope of this article. Which basically means that I am getting lazy.

--

--