Personal Web Page

Wednesday, June 24, 2009


Code deployment with Puppet

I fielded a question from Matt on the NYC*BSD discussion list about using Puppet to do code deployment from a subversion repository to his web servers. Some time ago I came up with a nice way to do this but hadn't published the code for it anywhere. This works for me, but tmtowtdi and ymmv.

I have developers create a tag for the version they want deployed, then I define in the web server manifest (which is in subversion itself) an instance of a custom resource that manages subversion working copies given the url of the repository, which branch to use, and the path of the copy directory.

Using a working copy rather than an export makes upgrading code fast but leaves .svn directories lying around, so I have Apache configured to hide them with 404s. The code is short and simple, since it just abuses exec to run the svn binary to do a check out, check which version is in place, and switch to a newer branch if necessary.

# web-foo.pp
class web-foo {
if $branch {
subversion::workingcopy { foo:
repourl => '',
branch => "$branch",
copydir => '/www/foo',

# modules/subversion/manifests/init.pp
class subversion {
package { subversion:
ensure => installed,
define subversion::workingcopy ($repourl, $branch, $copydir) {
include subversion
file { "$copydir":
owner => apache, group => apache, mode => 755,
ensure => directory,
# initial check out
exec { "svnco-$name":
command => "/usr/bin/svn co --non-interactive $repourl/$branch $copydir/$name",
creates => "$copydir/$name/.svn",
require => [Package[subversion], File["$copydir"]],
# switch branches
exec { "svnswitch-$name":
command => "/usr/bin/svn switch --non-interactive $repourl/$branch $copydir/$name",
unless => "/usr/bin/svn info $copydir/$name|/bin/grep -q 'URL:.*$branch\$'",
require => [Package[subversion], File["$copydir"], Exec["svnco-$name"]],

When the developers want me to deploy a new tagged version, I just change the value of the $branch variable to the name of the new tag. I use an external classifier, iClassify, which is a Ruby on Rails application that serves as a nice tagging interface for mapping nodes to classes and setting the values of variables. On its next run, Puppet sees that the working copy is the wrong version and switches to the new one. So, basically this provides declarative configuration of what code is on which servers with point and click deployment of new versions.

Labels: , ,


Post a Comment

<< Home
My Photo
Name: Jared Brothers
Location: New York, NY, United States


November 2008   December 2008   January 2009   June 2009   July 2009  

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]