Elastic Load Balancing on EC2

For the past few months we've been loading balancing the Galaxy Zoo web and API layers using HAProxy. Overall this has worked pretty well; HAProxy is easy to configure and hasn't missed a beat, however having to spend $150 per month just to load balance our other EC2 nodes seems a little excessive.

For some time Amazon have been promising load balancing and auto-scaling as part of their EC2 offerings and a few weeks back now a public beta of their auto-scaling and load balancing products was announced on their blog.

It's been a busy few weeks at the Zoo and so I've only just got around to playing with the new tools and I have to say, I'm impressed. In approximately 15 minutes I've managed to swap out one of our HAProxy nodes for an elastic load balancer (ELB). Count the steps:

1. Create a new load balancer

First we need to create an elastic load balancer. Note I'm using http and https, unfortunately ELB doesn't have SSL termination capability so you need to route traffic on port 443 to an alternative port (in my case I'm routing SSL to port 8443).

>> elb-create-lb LoadBalancerName --zones us-east-1b --listener "lb-port=80, instance-port=80, protocol=TCP" --listener "lb-port=443, instance-port=8443, protocol=TCP"

2. Register the instances to be load balanced

>> elb-register-instances-with-lb LoadBalancerName --instances instance_id

3. Create a CNAME record for the elastic load balancer

Each load balancer is given an AWS hostname such as loadbalancername-123456789.us-east-1.elb.amazonaws.com. This needs to be aliased to the actual hostname you want to use your load balancer using a CNAME record.

4. Add a health check

Last thing to do is add a instance health check to the load balancer so that it doesn't send requests to a unresponsive node. You can configure a health check like this:

>> elb-configure-healthcheck LoadBalancerName --healthythreshold 2 --interval 30 --target "TCP:8443" --timeout 3 --unhealthythreshold 2

This health check is set up to verify the status of each load balanced node every 30 seconds on port 8443, removing it from service if it fails more than two times.

5. Done!

And that's it. A couple of points to note: At the moment it's a limitation of the service that you can't have a root domain url load balanced using ELB. This is basically because you can't have a CNAME record pointing to the root of a domain. This is a known limitation and and should be fixed in the next release. Also elastic load balancing obviously isn't free (what is these days). The good news is though, at $0.025/hour, running an elastic load balancer is significantly cheaper than running a single EC2 HAProxy node ($0.10/hour).

» What's next?

Next up is configuring auto-scaling and monitoring using Cloudwatch. More of that later...