jmtd → log → puppet
As a first step on the road to evaluating different configuration management systems, I set up two VMs to test out puppet.
Puppet is conveniently packaged within Debian so client and server
installation was very simple. By default, puppet clients will look for a host
named puppet
on the local network, so by naming the server sensibly the two
started talking to each other. puppetca --sign [client hostname]
on the
server started the ball rolling.
My first test configuration was to add a user to the sudoers
file. With
CF Engine 2, I would have achieved this by using editfiles
to check for a
regular expression and insert a line if necessary. I stumbled across some
CF Engine-style definitions for puppet in a Debian Administration
article (taken originally
from puppet's own wiki, which have since been moved/deleted) and achieved it
using
append_if_no_such_line { sudo:
file => "/etc/sudoers",
line => "jon ALL=(ALL) ALL"
}
I'm a little concerned that this approach to problem solving is no better
than CF Engine 2, and in fact worse than how I'd do it with CF Engine 2: if the
host had a line with a different quantity of whitespace, such as jon ALL=(ALL) ALL
, it won't match exactly and a
duplicate line will be appended, whereas with CF Engine 2 I would have checked
for something like ^jon \+ALL=(ALL) \+ALL$
.
I set up my work laptop as another test node, and used puppet to install some packages that I commonly use:
class jon-desktop {
package { ['icedove', 'git-core', 'vim-gnome', 'vinagre', 'build-essential',
'devscripts', 'subversion', 'git-buildpackage', 'mutt',
'offlineimap', 'ascii', 'gitk', 'chromium-browser'
]: ensure => installed }
}
This worked fine, but is a little verbose and the package list is awkward to maintain buried inside the puppet syntax. I spent some time trying to see whether I could populate a puppet list based on the contents of a file: then I could list the packages one-per-line in a separate file. I haven't found a way of doing that yet.
Using my laptop as a second node also exposed some interesting puppet client
behaviour. Once I went off-site, the laptop tried to look up puppet
on
foreign networks (such as my home network). I would have assumed that, once
the strong SSL association had been made, the client would try to connect to
the FQDN of the server. This probably isn't a serious problem in practice,
as we probably won't need to rely on nodes off-site talking to the
configuration server, but I hope that the client doesn't trust any host that
happens to answer to puppet
...
I fixed this by hacking my hosts
file to include an entry for puppet
. I
could maintain this hack using Puppet itself, which would protect me against
stale definitions if any renumbering takes place. I could also have added a
line
server = puppet.fqdn.example.org
in /etc/puppet/puppet.conf
, which is a more robust way of solving the
problem.
Comments
Hi,
About I haven't found a way of doing that yet. sure it will be more elegant in Perl, Python, Ruby, whatever, but can be done using just bash:
Greetings, poisonbit (Iñigo).
Ick, I'd not realised that you could do cfengine in puppet -- how revolting.
Anyway, moving swiftly on, you should look at Augeas, and puppet-augeas, which lets you do stuff like this:
I've only written a few of these rules, so there are probably bugs in that, but the point is that Augeas reads config files into a tree structure, and lets you search that tree, and set new bits in it -- if your changes section actually changes anything, it then gets translated back into the format of the relevant config file.
An example I have tested, that adds an extra file to one's logrotate setup if not already present, is as follows:
This adds the dhcpd.log file entry after the last file entry in the daily set, but only if it's not already findable.