UPDATE: Amazon has now built ELB capability into OpsWorks, so you no longer need to use this workaround.


As you might have guessed by my recent posts I'm experimenting with the AWS OpsWorks platform.  I have been generally very pleased with everything except its lack of integration with existing AWS tools, specifically Elastic Load Balancers.  OpsWorks does include an HAProxy stack that you can use to load balance your system, but it lacks several features that ELB has and I find valuable.

To start, ELB is just easier to setup and manage.  Basically, you don't have to do anything at all with it, just create an ELB instance through the GUI and attach your instances to it.  It also multiple provides SSL termination points and automatically scales based on load.  To top it off, it's cheaper than running your own HAProxy stack through OpsWorks.  :)

The problem is that OpsWorks doesn't provide a way to integrate with ELB, at least not yet.  So you have to wire it up yourself.  This is not too big of a deal if you're already familiar with the AWS command line tools and Chef, which is what Amazon uses to manage their instances.  Unfortunately, I'm not super familiar with these things so I had to blindly work my way through the setup.  Here's how I did it.

1) Create an ELB in the normal way and give it some name "my-project-lb"

2) Create a custom Chef cookbook and check it into Github or store it in an S3 bucket or something.  It should look something like this:
$ mkdir -p cookbooks/aws/recipes
$ touch cookbooks/aws/recipes/default.rb
$ touch cookbooks/aws/recipes/register.rb
$ touch cookbooks/aws/recipes/deregister.rb

3) Edit the recipes in your cookbook to look something like this, replacing code as necessary:
## cookbooks/aws/recipes/default.rb
package "aws-cli" do
  action :install
end

## cookbooks/aws/recipes/register.rb
include_recipe "aws"

execute "register" do
command "aws --region #{node[:opsworks][:instance][:region]} elb register-instances-with-load-balancer --load-balancer-name my-project-lb --instances '{\"instance_id\":\"#{node[:opsworks][:instance][:aws_instance_id]}\"}'"
user "deploy"
end

## cookbooks/aws/recipes/deregister.rb
include_recipe "aws"

execute "deregister" do
command "aws --region #{node[:opsworks][:instance][:region]} elb deregister-instances-from-load-balancer --load-balancer-name my-project-lb --instances '{\"instance_id\":\"#{node[:opsworks][:instance][:aws_instance_id]}\"}'"
user "deploy"
end

3) Add your new cookbook to the OpsWorks custom Chef cookbook in your Application stack.

4) Finally, add your new recipes to the proper stack lifecycle events.  I chose Configure to run the "aws::register" recipe and  Shutdown to run the "aws::deregister" recipe.

Now just sit back and enjoy your new, cheaper, easier-to-use auto-balancing OpsWorks system.  :)