Puppet+Capistrano
I'm currently working on our upgrade to Puppet 2.6. One of the ideas I came up with was to deploy our puppet manifests (which we already store in a GIT repository) using Capistrano.
For those who don't know Capistrano already: Capistrano is a Ruby based deployment tool, used to get application code from a source control system to your application servers. Initially Capistrano was written to deploy Ruby on Rails applications. Meanwhile they also provide a 'railsless-deploy' module, which can be used to deploy any other code or framework.
What I like most about Capistrano, is that you don't have to install it on your servers. It's designed to read a couple of instructions from a "Capfile" which resides in the top directory of your application code. Once you trigger the deployment of a release, it will connect to your servers using SSH and trigger commands to deploy your Puppet manifests.
Important for all of this to work propperly is a SSH setup which uses public keys for authentication.

Capistrano will connect to the Puppet master and issue GIT commands against your GIT server. So not only password-less authentication to the puppet server must work, but also connecting from a shell on the Puppet server to the GIT server.
Installation
Capistrano is distrubuted as a ruby gem. If your distribution does already provide a package, use it. Otherwise you can simply use rubygems.
gem install capistrano
Capify
Next up copy the Capfile below, to your Puppet top level directory. Here is how it should look like:
-rw-r--r-- 1 sts sts 1499 Nov 26 10:33 Capfile -rw-r--r-- 1 sts sts 1464 Nov 9 20:02 README -rw-r--r-- 1 sts sts 907 Nov 9 20:04 TODO drwxr-xr-x 6 sts sts 204 Nov 9 20:02 manifests drwxr-xr-x 42 sts sts 1428 Nov 22 11:04 modules
There are some variables you need to change in order to make it work with your setup. Basically look through all lines which start with "set" and ajust them according to your needs.
Basically Capistrano is going to do the following:
- Connect to your puppet server.
- Create a directory for the release eg. /etc/puppet/git/#{:branch}/releases/20101125203021.
- Checkout the HEAD of the specified GIT branch to this directory, by connecting from your Puppet server, to your GIT server using SSH.
- Ajust the symlink from /etc/puppet/git/#{:branch}/current to point to the new release.
- Tell Fusion Passenger to reload the application code by creating the following file: /usr/share/puppet/rack/puppetmasterd/tmp/restart.txt
require 'railsless-deploy' require 'net/smtp' set :application, "puppet" set :user, "root" set :use_sudo, true set :group_writebale, false set :deploy_to, "/etc/puppet/git/#{:branch}" set :keep_releases, 2 set :scm, "git" set :repository, "git+ssh://[email protected]/srv/git/#{application}.git" set :branch, "master" role :app, "puppet.ono.at" namespace :deploy do task :default do update cleanup end task :notify do changes_list = "[email protected]" user_name = `git config user.name`.strip user_email = `git config user.email`.strip commits = `git log --pretty=oneline --abbrev-commit #{previous_revision}..#{current_revision}`.strip msg = To: #{changes_list} Subject: [puppet] deployed #{release_name}. The following changes where just pushed to puppet by #{user_name}: Branch : #{:branch} Release : #{release} Server : #{:app} Applied Commits /////////////////////////////////////////////// /////// #{commits} If you want to revert this release, please run: $ cap deploy:rollback Cheers, Capistrano. EOM Net::SMTP.start('localhost') do |smtp| smtp.send_message msg, user_email, changes_list end end dec "Restart Puppetmaster" task :restart, :roles => :app do run "touch /usr/share/puppet/rack/puppetmasterd/tmp/restart.txt" end end
Go
You should be able to deploy updates to your Puppet servers using the following command:
cap deploy
Future enhancements
If you've got any ideas or see a way to enhance this process, I'd be glad if you leave me a comment. :-)
read more
Comments