When working with an API Gateway in Amazon Web Services (AWS) you typically don't want the services themselves to be publicly available on the Internet. A public service would only create the need for extra layers of protections such as client certificates or service keys, neither of which would properly prevent a, for example, a DoS attack. A better approach is to either use Lambdas (which are private by default) or (if you can't use Lambdas) simply keep the services within a private cloud (a «VPC» in Amazon terminology) and provide access to them only through the API itself.
This quick-guide intends to explain the basics of configuring a private backend/service utilizing an Elastic Beanstalk app (EBS) residing within a VPC. The methods of the EBS will be made available through the API Gateway using a VPC Link.
Note: As of this writing the AWS API Gateway only allows a maximum of 5 VPC Links for one API Gateway in the same account. You can ask to have this limit increased through AWS support.
First, you will need to configure a Virtual Private Cloud (VPC), I will not cover this step here since it would require a separate post. However, I would recommend that you take a look at the following video for directions if you're unsure how to accomplish this step.
The second step is setting up an Elastic Beanstalk (EBS) application. (This guide assumes you're using the AWS console). One of the advantage of using EBS over pure EC2 instances is that EBS comes with a bunch of pre-configured features such as auto scaling and rolling updates. You can achieve the same goal (private service) using a just some EC2 instances and a Network Load Balancer (click the link to see how) of course, but for this guide I'll assume that you are using an EBS application.
The first step is to create an EBS application, followed by creating a new environment. The environment is actually where all the configuration takes place. Refer to https://aws.amazon.com/elasticbeanstalk for more information on how EBS actually works.
When setting up a new environment choose the "Web server environment" for now. Give your environment a name and choose a platform (I'm using Node.js). Just use the "Sample application" if you don't have a finished app bundle.
Important: Click the «Configure more options» button, not the «Create Environment»!
After you have clicked the «Configure more options» button you’ll find yourself on the «Configure <your env name>» page and you’ll see three radio buttons titled «Configuration presets». Choose the «High availability» option. This will give us the option to configure a Load Balancer. Now open / «modify» the «Load Balancer» tile. Choose the «Network Load balancer» and click «Save». The API Gateway VPC Link will only work with Network load balancers.
In the «Network» tile (left bottom one), select the VPC you have already created. Under «Load Balancer settings» the «Visibility» setting should be «Internal» since this service should not be accessible from the Internet. Select the private subnets (for all zones in your VPC) for both the load balancer and the subnets. No public subnets should be checked. Click «Save».
Setup anything else like scaling and so on and then click "Create environment».
Create an API Gateway if you haven't done so already.
- In the left menu, select «VPC links»
- Give the VPC link a name and select the Load Balancer you created under the EBS section in the «Target NLB». It will only show the (cryptic) name of the load balancer here, but if you go to the EC2 service, and select «load balancers» you can match any tags to the Load Balancer name.
- Click «Create».
While you wait for the connection to be created you can configure the API. I would recommend using stage variables to store a reference to the VPC link id. This would allow you to easier maintain several stages pointing to separate backends. AWS documentation for using stage variables to refer to a VPC link.
To configure a method in the api using the VPC link, see the following image.
In this example the «VPC link» is set as a stage variable, the same goes for the «Endpoint URI». As already stated, but worth repeating, this is a good idea because it makes it considerable easier to deal with multiple stages. You have to set this up for each of the methods in your api.