Replicating a Heroku-centric workflow within AWS

Giles Williams
Urban Massage Product
2 min readNov 24, 2014

We chose to host the majority of our platform on Heroku from day one having used it for previous projects — for a small team at small-ish scale, deploying maybe 10 times a day, there couldn’t be a better solution.

However, as we have grown at an amazing rate over the past 3–4 months, we quickly outgrew the initial cheap pricing of the Heroku platform (Heroku include a free instance for each app you run), along with all of the handy freemium-priced add ons available such as MySQL, Neo4J, RabbitMQ, redis and elastic search hosting.

We knew that before migrating and having to managing our own resources again, we needed to come up with a decent solution to replace the super-simple `git push` deploys that Heroku offered.

We had been using codeship.io as a platform to run all of our automated test suites whenever a branch is pushed to our Bitbucket repositories, but not really exploited the continuous delivery side of the service yet.

We ended up settling for ElasticBeanstalk (EB) over the option of managing our own instances and auto-scaling on EC2, so started with a test version of our API to try it out. We created a new Web Server application and environment in EB, selecting a Node.js configuration with the type set to Load balancing, autoscaling and chose MySQL as our database type.

EB allows you to set ENV variables to be passed into your application (similar to the `heroku config` command) so once those were copied over, we got to connecting codeship to our application in EB.

Adding a new deploy target in codeship is really easy (see these guides for more info about how to setup codeship with your git repository and getting your tests passing) — you just go to the Project Settings, select Deployment on the left, and choose the branch you wish to deploy and the deployment method. We always maintain `staging` and `production` branches, which each represent the release currently in each environment. We chose our `staging` branch, selected the ElasticBeanstalk target and entered our newly created IAM user and EB application / environment details.

After the next push, we had our app running on EB. We quickly updated the ENV variables for our app to use the RDS (MySQL) endpoint configured during setup of the EB environment, as well as creating a redis cluster via the ElastiCache AWS service and updating our cache URL ENV vars accordingly.

Once this was complete, we had a complete version of our environment running in AWS — we have always run our own Neo4J, RabbitMQ and elastic search instances / clusters on EC2 and were happy to continue doing so.

All-in-all, we managed to get deployments of our API down to about 1–2 minutes, including running our full test suite — compared to handling the deployment of code to multiple instances and implementing rolling updates, we were happy to go from 30 second (on Heroku) to 2 minute deploys!

--

--