puppet

From Glee
Jump to: navigation, search

Overview

Puppet, 'nuff said. Official Puppet Documentation.

Custom Modules

User Resources

I have quite a few (mostly) RHEL/CentOS-specific custom puppet modules :

Author Notes

Releasing :

cd modules/<modulename>
# Smoke testing
for i in tests/*.pp; do puppet apply --modulepath=`pwd`/.. --noop $i || ( echo "$i failed"; exit 1); done
puppet-module build .
# Result in pkg/

Generating documentation :

./gendoc
rsync -avP --delete doc/ bubble.marmotte.net:/srv/dl/puppet/doc

Manifest Tips

Hash sorting by key, to avoid puppet 2.7+ randomly changing the key order across runs :

<% variable_name.sort_by {|key, value| key}.each do |foo, bar| -%>

Master Bootstrapping

New Puppet Way

All-in-one chicken and egg solution, to get a new puppet master managing itself :

for MODULE in puppet selinux; do
 git clone git://github.com/thias/puppet-${MODULE} ${MODULE}
done
MASTER="puppet.example.com"
# Required more than once for the puppetmaster fact to be used
puppet apply --modulepath=. \
  -e "class { 'puppet::agent': puppet_server => '${MASTER}' } -> class { 'puppet::master': certname => '${MASTER}' }"

Old Manual Way

It's nice to have a puppet module to configure puppet masters, but there's a chicken-and-egg problem for the first one. Here are quick steps to bootstrap one on RHEL6/CentOS6 with SELinux enabled. Tested on RHEL6 :

yum install puppet-server policycoreutils-python
mkdir -p /etc/selinux/local/puppetmaster
cd /etc/selinux/local/puppetmaster/
cat > messages << 'EOF'
avc:  denied  { search } for  pid=1368 comm="puppetmasterd" name="/" dev=sysfs ino=1 context=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:sysfs_t:s0 tclass=dir
avc:  denied  { search } for  pid=1910 comm="puppetmasterd" name="/" dev=sysfs ino=1 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:sysfs_t:s0 tclass=dir
avc:  denied  { getattr } for  pid=1368 comm="puppetmasterd" path="/usr/bin/chage" dev=vda1 ino=4005 context=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:passwd_exec_t:s0 tclass=file
avc:  denied  { execute } for  pid=1368 comm="puppetmasterd" name="chage" dev=vda1 ino=4005 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:passwd_exec_t:s0 tclass=file
avc:  denied  { name_bind } for  pid=1495 comm="puppetmasterd" src=13808 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=udp_socket
avc:  denied  { node_bind } for  pid=1495 comm="puppetmasterd" src=20571 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:node_t:s0 tclass=udp_socket
avc:  denied  { getattr } for  pid=1586 comm="puppetmasterd" path="/usr/bin/chage" dev=vda1 ino=4005 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:passwd_exec_t:s0 tclass=file
avc:  denied  { read } for  pid=1650 comm="puppetmasterd" name="config" dev=vda1 ino=11895 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:selinux_config_t:s0 tclass=file
avc:  denied  { relabelfrom } for  pid=1650 comm="puppetmasterd" name="serial" dev=vda1 ino=14200 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=unconfined_u:object_r:puppet_var_lib_t:s0 tclass=file
avc:  denied  { relabelto } for  pid=1822 comm="puppetmasterd" name="serial" dev=vda1 ino=16975 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:puppet_var_lib_t:s0 tclass=file
avc:  denied  { open } for  pid=1822 comm="puppetmasterd" name="config" dev=vda1 ino=11895 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:selinux_config_t:s0 tclass=file
avc:  denied  { getattr } for  pid=1870 comm="puppetmasterd" path="/etc/selinux/config" dev=vda1 ino=11895 scontext=unconfined_u:system_r:puppetmaster_t:s0 tcontext=system_u:object_r:selinux_config_t:s0 tclass=file
EOF
audit2allow -M localpuppetmaster -i messages; semodule -i localpuppetmaster.pp
vi /etc/puppet/manifests/site.pp
service puppetmaster start