puppet with git
I’ve worked with cfengine in the past and really like it. It really cuts down on management for the systems that used it. For my home network I thought I try something else, that something turned out to be puppet.
I must say that I already like it more than cfengine as you can write much smaller manifests.
goals⌗
I want to centralize the management of the files in /etc and I want to keep track of changes of the file. For the management I’m going with puppet and for the versioning I choose git.
My main puppet server is called elektron.atoom.net. The first client is also elektron.atoom.net so this server is both server and client.
initial setup⌗
First install puppet, I’m not going into much detail here. Next install git. Then:
# cd /etc/puppet
# git-init-db
So you we have created a git-repository in /etc/puppet. The default puppet install on Debian/Ubuntu places some of the following files in /etc/puppet:
files/
fileserver.conf
manifests/
puppetd.conf
puppetmasterd.conf
In files/ you place whole files you want to manage with puppet - I will come to that later. Important now are fileserver.conf, puppetd.conf and puppetmasterd.conf.
Setting up the master⌗
The master daemon is called puppetmasterd and is controlled with the following files:
fileserver.conf:
[files]
path /etc/puppet/files
allow 192.168.1.2
allow 127.0.0.1
The path statement tells puppetmasterd that it can find the files in the /etc/puppet/files directory.
I haven’t touch the file puppetmasterd.conf
, and gone with my distribution’s default.
The client⌗
The client is called puppetd and uses the puppetd.conf
for its configuration. The only important
change I’ve made is that I’ve added server=elektron.atoom.net
to it.
Writing manifests
puppet
works by reading manifests which then get ’executed’ on the target system. I’m not
following the preferred set of directories as I consider those a bit overkill for my small setup.
In /etc/puppet/manifests
I do have the following:
etc.pp
site.pp
site.pp
is the default file that gets read by puppetmasterd
, in there you specify which hosts
(called nodes in puppet) get which configuration. As I only configure 1 machine at the moment
I only have:
import "etc.pp"
node 'elektron.atoom.net' {
include etc
}
The file etc.pp
defines one class: etc
which I include in the configuration for elektron.atoom.net.
For my other (soon to be added) machine called “foton” I will need another node
-statement. I needed
to put the name elektron.atoom.net
in single quotes to make this work, double quotes didn’t cut it
for me.
etc.pp⌗
The file etc.pp
looks like this: (I’ve added line numbers)
1 class etc {
2 file { "/etc":
3 source => "puppet://elektron.atoom.net/files/elektron/etc",
4 recurse => true
5 }
6
7 file { "/etc/inetd.conf": owner => root, group => root, mode => 644,
7.5 source => "puppet://elektron.atoom.net/files/elektron/etc/inetd.conf"}
8 file { "/etc/motd.tail": owner => root, group => root, mode => 644,
8.5 source => "puppet://elektron.atoom.net/files/elektron/etc/inetd.conf"}
9
10 service { inetd:
11 ensure => true,
12 pattern => "/usr/sbin/inetd",
13 subscribe => FILE["/etc/inetd.conf"]
14 }
15
16 exec { "Create /etc/motd":
17 subscribe => FILE["/etc/motd.tail"],
18 logoutput => true,
19 refreshonly => true,
20 command => "/bin/uname -snrvm > /var/run/motd; /bin/cat /etc/motd.tail >> /var/run/motd"
21 }
22 }
I will go by this line-by-line.
- 1: define a new class called
etc
. - 2: The concerns the file “/etc” - which ofcourse is a directory.
- 3: This defines what to put in this directory: namely files from
/etc/puppet/files/elektron/etc
. now all files in that directory will get copied to/etc
. Note the source syntax uses/etc/puppet
as a basedir, alltough we’ve specified/etc/puppet/files
infileserver.conf
. - 4:
recurse
is used to say that all files in files/elektron/etc should be monited. - 7: The files are named here so that they can be references by other puppet manifests.
- 7.5: Because I redefine the file
/etc/inetd.conf
I must tell puppet where to find it. - 8.5: And the same here for
/etc/motd.tail
. - 10: I use this to tell
puppet
that if the file/etc/inetd.conf
changes the service (daeamon)inetd
should be restarted. - 13:
subscribe
, watch the file/etc/inetd.conf
. My personal preference is to write this with all capitals. For puppet only the first character needs to be uppercased. - 16: Now I subscribe to
/etc/motd
. - 20: when the file changes puppet needs to perform the following command.
Now I only need to put my files in /etc/puppet/files/elektron/etc
and
puppet will miror them in the real `/etc’. Note that ownership and permissions are also exactly copied.
versioning
As said I will be using git
to version my files. This is relatively easy. First add the files
to your repository.
# cd /etc/puppet
# git-add files manifests
And then commit them:
# git-commit -a -m "committing my changes to /etc"
As git
doesn’t support the $Id$
tags that you might know from CVS and subversion I just
change my files to include the text string ## configured with puppet ##
.
Debugging and testing⌗
Just use:
# puppetmasterd -v
on the commandline and watch the output and correct any errors you might see.
The easiest way to debug and test puppetd
was also on the commandline, with:
# puppetd -v -o
You will get a lot of output telling you what happens. You can also debug a specific puppet manifest with:
# puppetd -v -o etc.pp