Deployment setup automation
George Malamidis, November 10th, 2009Part of my work these days has to do with building and deploying numerous experimental applications with varying life cycles. Many of these applications get built and put on a server in less than a day only to be shut down and never looked at again a couple of days later, others get turned off and revisited after some time, while others graduate to larger, wider scope systems.
This means that I get to deploy applications for the first time more frequently than usual. Also, because we deploy to virtualised infrastructures (including an internal cloud, Slicehost and Amazon EC2), slice instances (servers) tend to get rebuilt more often than they would in the absence of virtualisation. First time deployments are generally more involved than subsequent ones because there is setup up to be made and software to be installed in order for the host servers to accommodate the application.
One way to treat first time deployment woes is to create and maintain images of the system in the state required to host the application. I find this to work well when dealing with moderate numbers of applications and servers, whereas creating and keeping images up to date has a tendency to become tedious and inflexible as the number of applications and images increases.
As an alternative, we can move prerequisite system setup and installations responsibility closer to the application code, in the form of an after hook to the deploy:setup task that we call the first time we deploy an application with Capistrano. Here’s some Capistrano code that performs one time setup tasks.
namespace :util do
task :install_libraries do
sudo 'apt-get install libxml2 libxml2-dev libmysqlclient15-dev -y'
end
end
after 'deploy:setup', 'util:install_libraries'
With this approach, the application knows how to setup the system the way it needs it to be next time it gets deployed for the first time. As an added benefit, the Capistrano code serves as documentation for the application’s system requirements.

November 10th, 2009 at 3:15 pm
George,
Nice post. I’m very tempted to enhance this by calling a Puppet manifest (or if you really twisted my arm, Chef recipe) to manage all the dependencies, including crontabs, etc. Not a fan of sudo in Capistrano tasks generally but I’d probably make an exception in this case.
Best
Julian
November 17th, 2009 at 8:00 am
Have a look at Necktie: http://github.com/assaf/necktie/
It came out of a similar approach, but my Capistrano scripts quickly grew unmaintainable. So instead I check my Necktie script into Git, and use a Capistrano task (cap necktie) to pull it and run it on the remote server. A single script that runs locally (on the remote machine) is easier to work with.
http://blog.labnotes.org/2009/11/04/necktie-dress-to-impress/