Introduction

If you’re using the wonderful Puppet for configuration management you should seriously consider moving away from the stock WEBrick webserver to Passenger aka mod_rails. WEBrick doesn’t support concurrent clients and should only be used for early testing.

If you have more than 20-30 clients, you’re likely pushing what a WEBrick-driven puppetmaster can comfortably handle, even with splaying.

The instructions (older wiki version) on the Puppetlabs website are rather convoluted, thanks to dealing with various versions of Puppet, Passenger and different OSes.

Please note there are various gotchas and tweaks mentioned in Puppetlab’s instructions, this is the heavily edited version. If you want to tune passenger or have problems, it may be worth double-checking what the comprehensive instructions have to say.

I’ve just set up Puppet and Passenger on CentOS, using the pre-packaged versions available in the usual repos. No need to pollute your RHEL/CentOS machines with a mix of RPM and gem installs.

These instructions have been put together as I went and are just here as a reminder. These instructions work for me and a few other folk, your mileage may vary, et cetera, et cetera.

At the time of writing I’ve got these versions of things:

Use Puppet to Configure Puppet!

Since I wrote the instructions below, Matt Dainty has used them to produce a Puppet module which you can use to do all the hard work and set up a puppetmaster with passenger for you - no need to wade through all the steps below.

Matt’s module is puppet-bootstrap and is available on Github.

Manual Steps

Prerequisites

Puppetmaster and certificates

Ensure your puppetmaster works, particularly that SSL certificates have been generated.

Yum repository set-up

You’ll need the Puppetlabs repositories configured to pick up Passenger and some of its dependancies, as well as EPEL

The Yum repo config for Puppet repo can be had from installing the puppetlabs-release RPM:

rpm -Uvh http://yum.puppetlabs.com/el/5/products/i386/puppetlabs-release-5-1.noarch.rpm

Installation

Package installation

I’m a big fan of using the OS packaging system, rather than mixing OS and language packaging systems (i.e. RPM and gem) - things are less convoluted that way, as there is a single packaging system with the complete picture of what is installed on the machine.

yum install httpd mod_ssl rubygem-passenger

Puppetmaster configuration

You’ll need to add a couple of additional parameters to your puppetmaster configuration (/etc/puppet/puppet.conf):

[puppetmasterd]
    ssl_client_header = SSL_CLIENT_S_DN
    ssl_client_verify_header = SSL_CLIENT_VERIFY

Apache configuration

Next up, ensure that Passenger is configured appropriately

Create /etc/httpd/conf.d/puppermasterd.conf as follows, substituting FDQN for your Puppetmaster’s FQDN, and - although this config is correct at the time of writing - fixing up the version-component of the mod_passenger path if necessary:

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11
PassengerRuby /usr/bin/ruby

Listen 8140
<VirtualHost *:8140>

    SSLEngine on
    SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA
    SSLCertificateFile      /var/lib/puppet/ssl/certs/FQDN.pem
    SSLCertificateKeyFile   /var/lib/puppet/ssl/private_keys/FQDN.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>

Rack configuration

The Puppetmaster runs as a Rack application, and requires a config.ru file with the appropriate configuration directives.

You’ll also need to create the directory to hold the configuration (I admit I’ve not checked the purpose of the public and tmp directories at this time - they’re cargo-culted from the Puppet docs):

mkdir -p /usr/share/puppet/rack/puppetmasterd/{public,tmp}

The rack configuration varies across the different major Puppet versions (i.e. 0.24.x, 0.25.x and 2.6.x have different config).
This configuration is for 0.25.x (the version in EPEL) and is taken from puppetlabs github:

# a config.ru, for use with every rack-compatible webserver.
# SSL needs to be handled outside this, though.

# if puppet is not in your RUBYLIB:
# $:.unshift('/opt/puppet/lib')

$0 = "puppetmasterd"
require 'puppet'

# if you want debugging:
# ARGV << "--debug"

ARGV << "--rack"
require 'puppet/application/puppetmasterd'
# we're usually running inside a Rack::Builder.new {} block,
# therefore we need to call run *here*.
run Puppet::Application[:puppetmasterd].run

Lastly for the Rack configuration, the config must be owned by the puppet user - Passenger setuids to the user that owns the configuration.

chown puppet:puppet /usr/share/puppet/rack/puppetmasterd/config.ru

Start it all up!

With all the installation and configuration done, it should just be a case of stopping your puppetmaster (with its WEBrick server on port 8140) and starting up Apache (with Passenger on port 8140).

service puppetmaster stop
chkconfig puppetmaster off

service httpd start
chkconfig httpd on

Test your client(s), fix things as necessary.