using puppet

a system for automating system administration tasks

outline

  • overview of puppet
  • installing puppet
  • configuring puppetmaster
  • configuring fileserver
  • manifests
  • puppetca
  • configuring puppet client
  • augeas
  • installing augeas
  • using augeas
  • using augeas puppet
  • fun stuff

overview

More detailed "howto configure puppet"

installing puppet

Download from
http://reductivelabs.com/trac/puppet/wiki/DownloadingPuppet
or
http://reductivelabs.com/downloads/puppet/

Or use RPMS

configuring puppetmaster

the server is called puppetmasterd configuration stored in /etc/puppet/puppet.conf default installation requires no changes to startup.
[root@server ~] chkconfig puppetmaster on
[root@server ~] service puppetmaster start
Starting puppetmaster:                    [  OK  ]
puppetmasterd will start and listen on port 8140, you'll need to allow clients to connect to that port.
[root@server sysconfig]# iptables -I RH-Firewall-1-INPUT \
  -p tcp -m tcp -m state --state NEW,ESTABLISHED,RELATED \
  --destination-port 8140 -j ACCEPT
[root@server sysconfig]# iptables-save >iptables

fileserver

fileserver.conf
[facts]
	path /var/lib/puppet/facts
	allow *.example.com
[files]
	path /var/lib/puppet/files
	allow *.example.com
[web]
	path /var/lib/puppet/web
	allow www*.example.com
facts is a container for facter facts. files and web are file locations.

manifests

Manifests are puppet configuration files. they are used to describe functions, nodes, and installation classes.

It is good practice to separate out different functions, putting nodes in nodes.pp and functions in functions.pp or a similar naming convention. We default to making a new manifest for each class we define.

The first manifest is the master manifest (site.pp), it lists the other manifests that puppetmaster will load. puppetmaster only knows to load site.pp

site.pp

import "functions.pp"

import "nodes.pp"

import "auth.pp"

import "base.pp"

functions.pp

We'll define helpful functions here, since we defined this manifest first in site.pp, we can use any definitions in the subsequent manifests. We'll define a function called remotefile which defines a file to load from the puppet server
define remotefile($owner = root, $group= root, $mode, \
  $server = "server.example.com", $cls="base", \
  $backup = false, $recurse = false) {
	file {
	    $name:
            mode => $mode,
            owner => $owner,
            group => $group,
            backup => $backup,
            source => "puppet://$server/$cls/$name"
	}
}
puppet already has file defined, we have simply wrapped file in a function that sets some defaults for us.

functions.pp

append_if_no_such_line
define append_if_no_such_line($file, $line, $refreshonly = 'false') {
   exec { "/bin/echo '$line' >> '$file'":
      unless => "/bin/grep -Fxqe '$line' '$file'",
      path => "/bin",
      refreshonly => $refreshonly
   }
}
This is a generic function which looks for the argument $line using grep on $file. The appending is done with >> in the cmd argument for exec

nodes.pp

node client0 {
	include auth
}

node default {
	include base
}

base.pp

class base {
        remotefile { "/etc/syslog.conf": mode => 644 }
        remotefile { "/etc/logwatch/conf/logwatch.conf": mode => 644 }

        # time
        file { "/etc/ntp.conf": mode=> 644 }
        service { ntpd: ensure => true, enable => true }
}

See http://reductivelabs.com/trac/puppet/wiki/FunctionReference for details on the different functions available

auth.pp

class auth {
        # ldap
        remotefile { "/etc/ldap.conf": mode => 644, cls => "auth" }
        remotefile { "/etc/openldap/ldap.conf": mode => 644, cls => "auth" }

        # ns
        remotefile { "/etc/nsswitch.conf": mode => 644, cls => "auth" }

        # pam
        remotefile { "/etc/pam.d/system-auth": mode => 644, cls => "auth" }
}

quick type list

http://reductivelabs.com/trac/puppet/wiki/TypeReference

quick type list

examples

restarting a service when a file is changed (subscribe)
file { "/etc/nsswitch.conf":
    mode => 644,
    source => "puppet://server.example.com/etc/nsswitch.conf" }
service { nscd:
    ensure => true,
    enable => true,
    hasrestart => true,
    subscribe => File['/etc/nsswitch.conf'] }
service { messagebus:
    ensure => true,
    enable => true,
    hasrestart => true,
    subscribe => File['/etc/nsswitch.conf'] }

examples

or using exec
exec { "restart auth dependencies":
   command => "/sbin/service nscd stop; \
       /sbin/service nscd restart; \
       /sbin/service messagebus restart; \
       /usr/sbin/gdm-restart",
   logoutput => true,
   refreshonly => true,
   subscribe => File['/etc/nsswitch.conf'] }

examples

allowing httpd to connect to remote mysql (for example)
selboolean { httpd_can_network_connect:
    persistent => true,
    value => on }

configuring puppet client

/etc/sysconfig/puppet
PUPPET_SERVER=puppet.example.com
PUPPET_EXTRA_OPTS=--factsync

puppetca

signed keys in /var/lib/puppet/ssl/ca/signed
unsigned keys in /var/lib/puppet/ssl/ca/requests

signing policy
autosign.conf

*example.com
10.0.0.0/8

puppetca

[root@server ~]# puppetca --list
host.example.com
server.example.com
[root@server ~]# puppetca --clean host.example.com
Removing /var/lib/puppet/ssl/ca/requests/host.example.com.pem
[root@server ~]# puppetca --sign server.example.com
Signed server.example.com
[root@server ~]# puppetca --list
No cerificates to sign
[root@server ~]# puppetca --list -a
+ server.example.com

augeas

Augeas - a configuration API

http://augeas.net/

installing augeas

http://augeas.net/download/

RPM

using augeas

Quick start guide at http://augeas.net/tour.html

Configure ssh to not allow PasswordAuthentication

[root@server ~] export AUGEAS_ROOT=/root/augeas-sandbox
[root@server ~] mkdir $AUGEAS_ROOT
[root@server ~] cp -pr /etc $AUGEAS_ROOT
[root@server ~] grep PasswordAuthentication augeas-sandbox/etc/ssh/sshd_config
#PasswordAuthentication yes
# PasswordAuthentication, PermitEmptyPasswords, and 
[root@server ~] augtool -b
augtool> set /files/etc/ssh/sshd_config/PasswordAuthentication no
augtool> save
Saved 1 file(s)
[root@server ~]# grep PasswordAuthentication augeas-sandbox/etc/ssh/sshd_config
#PasswordAuthentication yes
# PasswordAuthentication, PermitEmptyPasswords, and 
PasswordAuthentication no

puppet augeas

http://reductivelabs.com/trac/puppet/wiki/PuppetAugeas

Same configuration change we did with augtool

class ssh {
        augeas{ "ssh":
                context => "/files/etc/ssh/sshd_config",
                changes => [
                        "set PasswordAuthentication no"
                ],
                notify => Service["sshd"]
        }
        service{ sshd: ensure => true, enable => true, hasrestart => true }
...
}
configuration change triggers sshd restart

fun stuff

advanced puppet

mysql storage

/etc/puppet/puppet.conf
[puppetmasterd]
        storeconfigs = true
        dbadapter = mysql
        dbuser = puppet
        dbpassword = "reductiveLabs"
        dbserver = localhost
        dbsocket = /var/lib/mysql/mysql.sock

ssh keys

class ssh {
	case $sshrsakey {
		"": { # ignore empty keys
		}
		default: {
			@@sshkey {"$hostname": 
				type => rsa,
				key => $sshrsakey, 
				alias => $fqdn }
			@@sshkey {"$ipaddress_eth0": 
				type => rsa,
				key => $sshrsakey }
		}	
	}
	Sshkey <<| |>>
}
greatly simplified example, proper class file here. This example uses mysql to store ssh keys that are exported using the @@ operator. http://reductivelabs.com/trac/puppet/wiki/ExportedResources

puppet ldap

http://reductivelabs.com/trac/puppet/wiki/LDAPNodes

store puppet class information for hosts in ldap*

[puppetmasterd]
        node_terminus = ldap
        ldapserver = ldap.example.com
        ldapbase = ou=hosts,dc=example,dc=com

*requires ruby-ldap

questions/resources

My instructions on setting up an install server
questions?