Rake task to deploy to AWS OpsWorks
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.