Deploy An API On Amazon EC2 For AWS Rookies

SaaS On-premises 2.0
At 3scale we find Amazon to be a fantastic platform for running APIs due to the complete control you have on the application stack. However, for people new to AWS, the learning curve is quite steep. So we put together our best practices into this short tutorial. Besides Amazon EC2, we’ll use the Ruby Grape gem to create the API interface and an NGINX gateway to handle access control. Best of all everything in this tutorial is completely free.

Prerequisites

For the purpose of this tutorial you’ll need a running API based on Ruby and Thin server. If you don’t have one you can simply clone an example repo as described below in the “Deploying the Application” section.

We’ll begin with the creation and configuration of the Amazon EC2 instance. If you already have an EC2 instance (micro or not), you can jump to the next step, “Preparing Instance for Deployment”.

Create and configure EC2 instance

Start by signing up for the Amazon Elastic Compute Cloud (Amazon EC2). The free tier is enough to cover all your basic needs. Once the account is created, go to the EC2 dashboard under your AWS Management Console and click on the “launch instance” button. That will transfer you to a pop-up window where you’ll continue the process:

  • Choose the classic wizard
  • Choose an AMI (Ubuntu Server 12.04.1 LTS 32bit, T1micro instance) leaving all the other settings for “instance details” as default
  • Create a key pair and download it. This will be the key that you’ll use to make an ssh connection to the server. It’s VERY IMPORTANT!
  • Add inbound rules for the firewall with source always 0.0.0.0/0 (HTTP, HTTPS, ALL ICMP, TCP port 3000 used by the Ruby Thin server)

Prepare instance for deployment

Once the instance is created and running, you can connect there directly from the console (Windows users from PuTTY). Right click on your instance, connect, and choose Connect with a standalone SSH Client.

Connecting to the Amazon Instance

Follow the steps and change the username to “ubuntu” (instead of “root”) in the given example.

connecting_linux_response

 

After executing this step you are connected to your instance. You’ll have to install new packages. Some of them require root credentials, so you’ll have to set a new root password: sudo passwd root. Then login as root: su root.
Now with root credentials, execute: sudo apt-get update
Switch back to your normal user with exit command and install all required packages:

  • Install the libraries that will be required by rvm, Ruby, and Git:
    sudo apt-get install build-essential git zlib1g-dev libssl-dev libreadline-gplv2-dev imagemagick libxml2-dev libxslt1-dev openssl zlib1g libyaml-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison libpq-dev libpq5 libeditline-dev
    sudo apt-get install libreadline6 libreadline6-dev
  • Install Git (on Linux rather than from Source)
  • Install rvm
  • Install Ruby
    rvm install 1.9.3
    rvm use 1.9.3 --default

Deploying the application

Our example, the Sentiment API, is located on GitHub. Try cloning the repository:
git clone git@github.com:jerzyn/api-demo.git
You can review the code and tutorial on creating and deploying this app here and here. Note the changes — we’re using only v1, as authentication will go through the gateway.

Now you can deploy the app by issuing bundle install.
Now you can start the thin server: thin start.

To access the API directly (without any security or access control) access: your-public-ip:3000/v1/words/awesome.json You can find your public IP in the AWS EC2 Dashboard > Instances in the details window of your instance.

AWS Details and public IP

Optional

If you want to assign a custom domain to your Amazon instance, you’ll have to do one thing: Add an A record to the DNS record of your domain, mapping the domain to the public IP address.

Your domain provider should either give you some way to set the A record (the IPv4 address), or it will give you a way to edit the nameservers of your domain. If they don’t allow you to set the A record directly find a DNS management service, register your domain as a zone there, and the service will give you the nameservers to enter in the admin panel of your domain provider. You can then add the A record for the domain. Some possible DNS management services include ZoneEdit (basic, free) or Amazon route 53.

At this point, your API is open to the world. This is good and bad—it’s great that you’re sharing, but bad that without rate limits a few apps could kill the resources of your server and you would have no insight into who is using your API and how it’s being used. The solution is to add API management.

Enabling API management with 3scale

Rather than reinventing the wheel and implement rate limits, access controls, and analytics from scratch, you can leverage the 3scale API Management Platform. Sign up for a 3scale account if you haven’t already, activate it, and log in through the links provided. The first time you log in, some sample data will be created for you so you’ll have an API key to use later. You can go through the wizard to get an idea of the system’s functionality (optional). Then start with the implementation.

To get some instant results, we’ll start with the API gateway in the staging environment which can be used while in development. Then we’ll configure an NGINX gateway that can scale up for full production deployments. Here’s some documentation on the configuration of the API gateway, as well as more advanced configuration options.

Once you’ve signed in to your 3scale account, go to Dashboard > API > Select the service (API) > Integration > edit integration settings and then choose APIcast Self-managed.

Proxy Integration
Proxy Integration2

Set the address of of your API backend. This has to be the public IP address unless the custom domain has been set, including http protocol and port 3000. Now you can save the changes to the API gateway in the staging environment to test your API by hitting the staging endpoint.

http://api.XXX.proxy.3scale.net/v1/words/awesome.json?user_key=USER_KEY

Where XXX is specific to your 3scale account and USER_KEY is the authentication key of one of the sample applications created when you first logged into your 3scale account. (If you missed that step just create a developer account and an application within that account.)

Try it without app credentials; next with incorrect credentials; and then once authenticated, within and over any rate limits you have defined. Once it’s working to your satisfaction you can download the config files for NGINX.

Note

Whenever you have errors, check whether you can access the API directly: your-public-dns:3000/v1/words/awesome.json. If that is not available, you need to check whether the AWS instance is running and whether the Thin server is running on the instance.

Install and deploy APIcast (your API gateway)

Finally, to deploy install and deploy APIcast, follow the steps in the APIcast 2.0 self-managed tutorial for 'local' deploy.

You’re almost finished! The last step is to start the NGINX gateway and put some traffic through it. If it’s not running yet (remember the Thin server has to be started first), go to your EC2 instance terminal (the one you were connecting through ssh before) and start it now.

The last step will be verifying that the traffic goes through with a proper authorization. To do that, access:

http://your-public-ip/v1/words/awesome.json?app_id=APP_ID&app_key=APP_KEY

where APP_ID and APP_KEY are key and ID of the application you want to access through the API call.

Once everything is confirmed as working correctly, you’ll want to block public access to the API backend on port 3000, which bypasses any access controls.