Choosing an open source configuration management software – Part 2

Ok, we were talking about Puppet vs Cfengine. Both are open source configuration management software.
Cfengine is much older and I think still has more users as it’s been well known for some time. This article is ment to be little presentation of Puppet which I have chose as cfengine replacement in our company network.
To be honest, I am using puppet just for about one month but I dare to claim I am pretty familiar with it and able to manage the same range of server configuration as I did (and saw) with cfengine.

Let’s look at few things that are being made differently with Puppet. Stupid thing about cfengine was that each managed server downloaded all files placed in /var/cfengine/conf where were placed all files for all servers what led to total mess everywhere. Puppet has solved this boring thing by implementing something what is called File Server. It’s intended to run File Server on puppet server besides managed servers fetch all needed files from there. The default location for the file service is /etc/puppet/fileserver.conf and is configured very easily in few seconds and could seem for example like this:

[export1]
path /export
allow 127.0.0.1
allow 192.168.0.*

[export2]
path /export2
allow 127.0.0.1
allow 192.168.1.*

This simple example defines two file server repositories each accessible from different IP range. Such repository can then be very easily set as a source of configuration files for managed servers in /etc/puppet/manifests/site.pp which is main configuration file ( something like cfagent.conf in Cfengine ):

file { “/etc/resolv.conf”:
source => “puppet://puppetserver.mydomain.com/export2/new_resolv.conf”,
owner => root, group => root,
}

Please note, that this example won’t work as it is, since we didn’t define for what nodes this action should be run.
Another thing where I saw difference between cfengine and Puppet at first sight was grouping things together ( what actions are run on what servers ). Ok, speaking in terms of Cengine those are groups:

groups:
srv_group1 = ( 10.0.0.1 10.0.0.2 10.0.0.3 )

copy:

srv_group1::
$(master_input_dir)/conf/new_resolv.conf dest=/etc/resolv.conf
mode=0644
owner=root
group=root

In Puppet, similar action would be defined in following way:

node “10.0.0.1”, “10.0.0.2”, “10.0.0.3” {
include common
}

class common {

file { “/etc/resolv.conf”:
source => “puppet://puppetserver.mydomain.com/export2/new_resolv.conf”,
owner => root, group => root,
mode => 0644
}
}

This example instructs Puppet to fetch file new_resolv.conf from Puppet repository called export2 running on File Server puppetserver.mydomain.com. As you see configuration of File Server as well as using it as source for copying files to managed server(s) is very easy.

Ok, we understand File Server and now we saw what must be done to manage our servers. See, that idea of Puppet in contrast to Cfengine is to group different actions into classes and then call those classes ( see “include common” in our example ) for specific groups of managed servers rather then define groups of servers and then specify what is done for every single group in each action section (copy,packages,links etc..)

Another interesting thing about Puppet is templating support. Stupid example:

content of /etc/puppet/manifests/site.pp

node ‘10.0.0.1’ {
include test
}

class test {

$name = $fqdn
$ip = $ipaddress

file { “/tmp/test”:
owner => root, group => root,
mode => 440,
ensure => “present”,
content => template(“/var/lib/puppet/templates/test.erb”)
}

}

content of /var/lib/puppet/templates/test.erb:

Servername <%= server %>
Ipaddress <%= ip %>”

Note that variables like $fqdn or $ipaddress are replaced with appropriate values of each node where template is applied. You can run facter command to see these values. Another interesting thing is that template values are filled in on Puppet server and afterwards sent to nodes.

This is just demonstration how templating works. I hope you won’t struggle as I did when I was trying to try templating for first time as this area is not very well documented on Puppet site.

If you are somehow experienced with Cfengine you remember that you had to define action sequence ( e.g: actionsequence = copy packages editfiles shellcomands ). I’ve seen this caused many problems when something wasn’t copied (copy) at time when for example shellcommand requested this file and changing action sequence caused later some more hidden problems. I just want to say that Puppet hasn’t anything such stupid as action sequence and all relations between actions can be solved separately:

node ‘10.0.0.1’ {
include test
}

class test {

file { “/etc/httpd/conf/httpd”:
owner => root, group => root,
mode => “600”,
source => “puppet://puppetserver.mydomain.com/export2/httpd.conf”,
require => package[“httpd”]
}

package { “httpd” :
ensure => installed
}
}

This example demonstrates how easy is to setup relations between specific actions. Before we copy httpd.conf file from Puppet server we want Puppet to check whether httpd package is installed. Puppet will automatically find suitable packaging software and install such package if not present.

Puppet service management is also worth mentioning.

node “10.0.0.1”, “10.0.0.2”, “10.0.0.3” {
include common
}

class common {

package { “httpd” :
ensure => installed
}

service { httpd:
name => “httpd”,
ensure => running,
hasrestart => true,
enable => true,
require => [ package[“httpd”] ]

}
}

By this simple example we make sure that httpd package is installed, is running ( ensure => running ) and is started on boot ( enable => true ). Puppet will find suitable tool to make this service start on boot ( e.g: chkconfig for SLES)

I think I have covered all interesting Puppet’s features including templating, action sequence replacement, file server instead of copying everything on all nodes. Feel free to send your comments. If you mean it with Puppet seriously you can start reading Installation Guide and Puppet Introduction

Posted in network administration software, Network Topology


Leave a Reply