Puppet: System Administration Automated

Support

Using Passenger

This support is present in release 0.24.6 and later versions only - it is not supported in earlier releases

Alternatively see: Using Mongrel

Why You'd Do This

Traditionally, the puppetmaster would embed a WEBrick or Mongrel Web Server to serve the puppet clients. This may work well for you, but a few people feel like using a proven web server like Apache would be superior for this purpose.

What is Passenger ?

Passenger (AKA mod_rails or mod_rack) is the Apache 2.x Extension which lets you run Rails or Rack applications inside Apache.

Puppet (>0.24.6) now ships with a Rack application which can embed a puppetmaster. While it should be compatible with every Rack application server, it has only been tested with Passenger.

Installation Summary

Make sure puppetmasterd ran at least once, so the SSL certificates got set up.

Install Apache 2, Rack and Passenger:

apt-get install apache2
gem install -v 0.4.0 rack
gem install passenger
passenger-install-apache2-module

Enable Apache modules "ssl" and "headers":

# for Debian or Ubuntu:
a2enmod ssl
a2enmod headers

Configure Apache:

cp apache2.conf /etc/apache2/conf.d/puppetmasterd  (see below for the file contents)
vim /etc/apache2/conf.d/puppetmasterd (replace the hostnames)

Install the rack application [1]:

mkdir -p /usr/share/puppet/rack/puppetmasterd
mkdir /usr/share/puppet/rack/puppetmasterd/public /usr/share/puppet/rack/puppetmasterd/tmp
cp config.ru /usr/share/puppet/rack/puppetmasterd
chown puppet /usr/share/puppet/rack/puppetmasterd/config.ru

Go:

/etc/init.d/apache2 restart

[1] Passenger will not let applications run as root or the Apache user, instead an implicit setuid will be done, to the user whom owns config.ru. Therefore, config.ru shall be owned by the puppet user.

Apache Configuration

This Apache Virtual Host configures the puppetmaster on the default puppetmaster port (8140).

Listen 8140
<VirtualHost *:8140>

	SSLEngine on
	SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA
	SSLCertificateFile      /var/lib/puppet/ssl/certs/puppet-server.inqnet.at.pem
	SSLCertificateKeyFile   /var/lib/puppet/ssl/private_keys/puppet-server.inqnet.at.pem
	SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem
	SSLCACertificateFile    /var/lib/puppet/ssl/ca/ca_crt.pem
	# CRL checking should be enabled; if you have problems with Apache complaining about the CRL, disable the next line
	SSLCARevocationFile     /var/lib/puppet/ssl/ca/ca_crl.pem
	SSLVerifyClient optional
	SSLVerifyDepth  1
	SSLOptions +StdEnvVars

	# The following client headers allow the same configuration to work with Pound.
	RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
	RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
	RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e

	RackAutoDetect On
	DocumentRoot /usr/share/puppet/rack/puppetmasterd/public/
	<Directory /usr/share/puppet/rack/puppetmasterd/>
		Options None
		AllowOverride None
		Order allow,deny
		allow from all
	</Directory>
</VirtualHost>

For details about enabling and configuring Passenger, see the Passenger install guide.

The config.ru file

# Author: Christian Hofstaedtler <hofstaedtler@inqnet.at>
# Copyright (c) 2007 Luke Kanies, 2008 Christian Hofstaedtler
#
# This file is mostly based on puppetmasterd, which is part of
# the standard puppet distribution.

require 'rack'
require 'puppet'
require 'puppet/network/http_server/rack'

# startup code stolen from bin/puppetmasterd
Puppet.parse_config
Puppet::Util::Log.level = :info
Puppet::Util::Log.newdestination(:syslog)
# A temporary solution, to at least make the master work for now.
Puppet::Node::Facts.terminus_class = :yaml
# Cache our nodes in yaml.  Currently not configurable.
Puppet::Node.cache_class = :yaml


# The list of handlers running inside this puppetmaster
handlers = {
	:Status => {},
	:FileServer => {},
	:Master => {},
	:CA => {},
	:FileBucket => {},
	:Report => {}
}

# Fire up the Rack-Server instance
server = Puppet::Network::HTTPServer::Rack.new(handlers)

# prepare the rack app
app = proc do |env|
	server.process(env)
end

# Go.
run app

The config.ru file for 0.25.x

The code has been a bit reshuffled in 0.25.x, so config.ru gets a lot simpler:

require 'puppet/network/http/rack'

loader = Puppet::Network::HTTP::RackLoader.new()
rack_handler = loader.get_handler()

# prepare the rack app
app = proc do |env|
  rack_handler.handle_request(env)
end

# Go.
run app