Introduction

I've spent the day building a deploy Rake task for my AWS OpsWorks environment and I thought I would share it with you.

My project is a pretty simple Sinatra application that is being hosted in Amzon's cloud environment (AWS) with the help of the OpsWorks tools.  One of the things I wanted to do is to make it easy to deploy the application from the command line.  I guess I've gotten lazy with Heroku's "deploy from a Git push" and I wanted something similar in my new environment.

After working out a couple of kinks, it wasn't too difficult really.  Here's how to set it up in your environment.  Basically, you just need to create a couple of files and fill in some default values from your OpsWorks environment.

The opsworks.yml file defines all the layer/app ID's in all the regions you want to deploy to.
# config/opsworks.yml
us-east-1:
layer_id: "your-layer-id"
app_id: "your-app-id"

us-west-1:
layer_id: "your-layer-id"
app_id: "your-app-id"

The Rakefile file defines the rake tasks needed to deploy your software. Just make sure that you have the 'aws-sdk' Gem installed and a valid AWS credentials. I'm using a config/aws.yml file but you can do whatever you like.
# Rakefile
require 'rubygems'
require 'bundler'
Bundler.require if defined?(Bundler)

# Authenticate to AWS
AWS.config(YAML.load_file('config/aws.yml')['production'])
client = AWS::OpsWorks.new.client

desc "Deploy the app to the LIVE environment"
task :deploy do
regions = YAML.load_file('config/opsworks.yml')

deploy_options = {}
deploy_options[:command] = {name:'deploy'}

# Loop through each region
regions.each do |region, options|
deploy_options[:instance_ids] = []
deploy_options[:app_id] = options['app_id']
deploy_options[:comment] = "rake deploy from '#{Socket.gethostname}'"
instances = client.describe_instances({layer_id: options['layer_id']})

next if instances.nil? || instances.empty?

# Capture the details for each 'online' instance
instances[:instances].each do |instance|
if 'online' == instance[:status]
deploy_options[:instance_ids] << instance[:instance_id]
deploy_options[:stack_id] = instance[:stack_id]
end
end

puts "Deploying to #{deploy_options[:instance_ids].count} instances in the #{region.upcase} region..."
client.create_deployment deploy_options
end
end

Usage


Just run rake deploy to deploy your code to any "online" instances that matches the regions/apps/layers in your config file.