Posts Tagged ‘puppet-tips-and-tricks’

Puppet Tips&Tricks: Running apt-get update only when needed

Tuesday, November 9th, 2010

A small example on how you can make apt-get update only run if a) the machine rebooted and b) something changed in /etc/apt. We use cron-apt to run an update every night, to keep the machine up-to-date, so this is really all we need. If you need to add a repository before you can install a package (say, you want to install a package from the Kumina Debian Repository), you can now do it in one puppet run, if you make sure your package resource depends on apt-get update. This is the code:

# Run apt-get update when anything beneath /etc/apt/ changes
exec { "apt-get update":
command => "/usr/bin/apt-get update",
onlyif => "/bin/sh -c '[ ! -f /var/cache/apt/pkgcache.bin ] || /usr/bin/find /etc/apt/* -cnewer /var/cache/apt/pkgcache.bin | /bin/grep . > /dev/null'",

Update aug 2 2011: Thanks to Enrique’s comment (see in the comments), we’ve made the script slightly prettier. Thanks Enrique!

Puppet Tips&Tricks: Variable variables

Wednesday, September 1st, 2010

Sometimes you want to use variable variables, for instance when you want to iterate over all the ipaddress_* facts that facter found. Using something like ${ipaddress_$if} doesn’t work, though. Inline_template to the rescue! Thanks to Volcane on IRC, this is a possible solution:

$ifs = split($interfaces,",")

define do_this {
	$mule = "ipaddress_${name}"
	$donkey = inline_template("<%= scope.lookupvar(mule) %>")

	notify { "Found interface $donkey":; }

do_this { $ifs:; }

This will output:

$ sudo puppet net.pp 
notice: Found interface
notice: //Do_this[eth0]/Notify[Found interface]/message: defined 'message' as 'Found interface'
notice: Found interface
notice: //Do_this[eth1]/Notify[Found interface]/message: defined 'message' as 'Found interface'

WordPress MU and /etc/hosts file

Monday, July 12th, 2010

Due to a silly networking problem originating from the LVS installation we’re using, we’re stuck with a setup in which machines in the DMZ cannot access themselves via their external addresses. This is a problem for several scripts which refer to their own URL when doing some maintenance. Especially with a certain WordPress MU installation managed by our friends from Interconnect IT, we ran into trouble when they tried to update their WordPress code.

Puppet to the rescue. Although not something I’m especially proud of, I can imagine other using this as an example to fix other problems. What we do is use the wp-config.php from the WordPress installation to get data from the database that WordPress MU connects to. We use a PHP script to retrieve that data and format it in a comma-separated-value list. We then use this output to create a Facter fact, which we use in puppet to create entries in the /etc/hosts file.

Puppet Tips&Tricks: checking if a value is present in an array

Thursday, June 17th, 2010

I tend to create fairly ubiquitous defines, which allow for a lot of functionality. For that, it would be nice if you could tell puppet “if value X is present in array Y, do this”. I made it a feature request for puppet (#3871), which was luckily accepted and will be implemented in the next version of puppet. However, for the time being I needed this fixed. So I spend some time creating an ugly solution for this in older versions of puppet. Hope it helps someone!

# Setup additional services for this vhost, if any are required.
# Start with a general check to prevent a lot of work when it's
# not needed.
if $allow != "" {
           # FIXME Ideally we want something that simply does
           #  for i in allow do include $http::allow_$i
           # but that doesn't work (yet?).
           # W00t! That's going to be added in 2.6! #3871
           if inline_template("<%= allow.include?('php5') %>") == "true" {
                     include allow_php5
           if inline_template("<%= allow.include?('rewrite') %>") == "true" {
                     include allow_rewrite
           if inline_template("<%= allow.include?('ruby') %>") == "true" {
                     include allow_ruby
           if inline_template("<%= allow.include?('python') %>") == "true" {
                     include allow_python

Puppet Tips&Tricks: testing your regsubst replacings

Monday, March 15th, 2010

This is part of an ongoing series. Check this for the complete series!

Regular Expressions are important for us. We use them a lot, mostly because it’s such a powerful tool. So our puppet recipes contain several regsubst calls too. One problem is usually that regex can be fairly complex and you’d like a nice way to check it out. After some talk on IRC (#puppet on freenode), monachus gave me some tips for this. Simply use the interactive Ruby shell, irb, for this.

Now, I wanted to check whether a certain string ended in “:ssl” or not. I tested my regex replacement as follows:

$ irb
>> s1=""
=> ""
>> s2=""
=> ""
>> s1.sub(/.*:(ssl)$/, "\\1")
=> "ssl"
>> s2.sub(/.*:(ssl)$/, "\\1")
=> ""