Elastic Beanstalk is a service for deploying and scaling web applications in the Amazon Web Services (AWS) cloud. I recently dove in head first with a Node.js app that I needed to deploy. I spent countless minutes spamming the refresh button and scouring Stack Overflow, but in the end, I learned quite a bit. Read on for some tips.
Elastic Beanstalk Overview
Amazon provides a curated collection of their services under the name Elastic Beanstalk for deploying scalable, production-ready web applications. A few of its competitors include Heroku, Google App Engine, and Microsoft Azure. Elastic Beanstalk is free to use but you pay for the underlying resources, including:
- Amazon EC2 – The server instances that will run your application code. These are normal EC2 instances; they show up on the AWS console’s Compute > EC2 page and you can SSH into them to do tasks as you normally would.
- Amazon S3 -A scalable storage service to back up your server logs and previous application versions.
- Amazon RDS / DynamoDB / SimpleDB – Chances are you’ll need some type of database for your application and another Amazon service will integrate seamlessly.
- For other third-party services, you’ll continue to use them and pay as you normally would.
There are several application platforms supported, such as Node.js, Python, Ruby, Docker, Java, and more. The application I deployed was powered by Express and Node.js, with nginx acting as the proxy server and Elastic Beanstalk handling the server load balancing.
Deploying the application is as easy as zipping the files, uploading them to the Elastic Beanstalk web interface, and waiting for the rollout to complete. AWS automatically saves old application versions to an Amazon S3 bucket for easy rollbacks (which I used multiple times). Of course, anything you can do from the GUI, you can also do via the command line.
There’s a nice enough dashboard for monitoring your environment’s general status…
…and some graphs for the data nerds in all of us.
An Elastic Beanstalk application is the top-level entity under which your resources sit. Within an application, you can have multiple environments. Each environment contains a load balancer, auto-scaling group, and EC2 instances. Each environment has a unique URL pointing to its load balancer. Environments can be created and destroyed at any time, and you can save an environment configuration to re-create it later.
I housed our web app in two Elastic Beanstalk environments under a single application. The first environment contained the production application, which took advantage of load-balancing and auto-scaling to maintain a balance between performance and cost. The second environment contained a single server as a low-cost testbed for application and settings updates.
The campaign incurred just under $500 in AWS costs over the 3-week period. The m1.large EC2 instance accounted for the lion’s share at 2,325 hours x $0.175/hour for a total of $406.88. Other paid Amazon services (S3, DynamoDB, and CloudWatch alarms) cost an order of magnitude less coming in under $40.
To calculate these numbers, I had to dig through tables, match instance types, and make other estimations based on all of the projects we host on AWS. In the future, I’ll surely use Cost Allocation Tags to avoid this. Cost Allocation Tags are labels that you can attach to any AWS resource to organize projects and track costs in a more detailed manner. Some tags are automatically generated when you initialize a resource, but they can also be manually created and assigned. After assigning and activating tags, AWS will automatically generate cost allocation reports by tag in the Billing and Cost Management console. Read more about Cost Allocation Tags here.
Not all EC2 instance types are available in the Elastic Beanstalk environment configuration. I would recommend setting up your project when you begin development so you’re aware of what type of server is backing your system.
Use a minimum of two servers in the load balancing configuration so your production environment can take advantage of rolling updates. This allows each server to de-register from the load balancer, update to a new version, and re-activate for no-downtime updates.
You can SSH into your server instances and perform actions manually from the command line. While this is useful for testing and debugging, you will need to write an .ebextension script that performs the action and upload that script with your application bundle to take advantage of Elastic Beanstalk’s auto-scaling functionality.
Speaking of .ebextension files, OS X does not compress hidden files by default. I spent a few hours trying to debug .ebextension files that were not running because they were not in the zipped application bundle. You can confirm those files by checking the eb-activity.log where the result of the unzip command is shown. To include hidden files when compressing from Finder:
- Show hidden files in Finder by running this terminal command: $ defaults write com.apple.finder AppleShowAllFiles YES
- Select the files you want to compress
- Right click and select “Compress X Items”
Time zones are no fun – make sure you double and triple check your work.
Amazon’s Elastic Beanstalk service is a cost-effective, scalable environment in which to run your web applications. It’s not without its quirks and isn’t the right fit for every project, but the platform condenses a magnitude of development into an easy-to-use service that allows just about anyone to deploy and manage a cloud-based service.
Check out the insanely great AWS Elastic Beanstalk Survival Guide by Colin Toh.
For de-mystifying the names of AWS offerings, see AWS in Plain English.
*Disclaimer: I am not responsible for any losses or damages from actions you take on your servers. This is simply me documenting my experience. Do your homework.
If you found this article useful, please tell me!