crapapult
Crapapult is a thin wrapper around Capistrano for the sole purpose of deploying services at Yammer.
What the hell is going on here
At Yammer, we use Hudson/Jenkins to build all of our JVM-based services. Each time we commit to the various branches of a service, Hudson runs all the tests and (if they pass, naturally) builds a fat, deployable JAR containing all the various dependencies.
Crapapult allows us to deploy new versions of our services and synchronize those deploys with changes to application-specific configuration. (We use Puppet to provision and maintain machines with broad roles but use Crapapult to generate all the application-specific configuration.)
It does so by using Capistrano to SSH into each of the application servers and
using curl
to download the last successful build artifact from the specified
Hudson job. This tends to be super-fast, especially if your CI box is located in
the same data center as your app servers.
Once the artifact is staged (by default in /opt/APPNAME
), it then uploads the
specified set of asset files to each server. After that, it renders and uploads
the specified set of template files to each server.
Then it restarts your service and gives you a high-five.
How to use this dang thing
Get yer install on:
gem install crapapult
Create yer dang deployer directory structure:
mkdir -p myapp-crapapult/{assets,templates}
cd myapp-crapapult
And start slingin' some crap in your Capfile
:
require "crapapult"
# Give your application a name.
application "myapp" do
# Upload the file in assets/myapp.jvm.conf to each host.
asset "myapp.jvm.conf", "/etc/myapp.jvm.conf"
# Render the ERB template in templates/myapp.conf.erb to each host.
template "myapp.conf.erb", "/etc/myapp.conf", :mode => "0600"
# Set up the file in assets/myapp.upstart as an Upstart config file and create
# an /etc/init.d/myapp script.
upstart "myapp.upstart"
end
# Specify where your Hudson/Jenkins server is.
hudson "http://build.example.com"
# Specify the various branches and their respective build jobs.
branch :master, "myapp-release"
branch :development, "myapp-development"
# Define environments with allowed branches.
environment :staging, [:master, :development] do
# Set environment-specific data for your templates to work with.
data :jdbc_url, "jdbc:postgresql://db.example.com/happy_fun_times"
host "myapp-001.staging.example.com" do
# Set host-specific data for your templates to work with.
data :worker_id, "1"
end
end
# This will disallow deploying the staging branch to production.
environment :production, [:master] do
# Set environment-specific data for your templates to work with.
data :jdbc_url, "jdbc:postgresql://db.example.com/happy_fun_times"
host "myapp-001.example.com" do
# Set host-specific data for your templates to work with.
data :worker_id, "1"
end
host "myapp-002.example.com" do
data :worker_id, "2"
end
end
Deploying a thing
cap deploy # Deploy the specified branch to the specified environment
cap from:development # Deploy the development branch
cap from:master # Deploy the master branch
cap to:production # Deploy to the production environment
cap to:staging # Deploy to the staging environment
So to deploy your development branch to your staging environment, it's just a simple:
cap from:development to:staging deploy
And you're off to the races.
Copyright (c) 2011 Yammer, Inc. See LICENSE.txt for further details.