Simplifying File Permissions in Puppet Manifests

I’ve been a user of Puppet for about three years now and while on a recent dig in to some of my older classes it was a little embarrassing to see lots of file types used like this:

  file { '/srv/whi/maps':
    ensure => present,
    source => "puppet://$servername/whi/maps.conf",
    owner  => 'whi',
    group  => 'whi',
    mode   => 0644,
  }
  file { '/srv/whi/elocs':
    ensure => present,
    source => "puppet://$servername/whi/eloc.conf",
    owner  => 'whi',
    group  => 'whi',
    mode   => 0644,
  }

Luckily as we get more experienced with a tool we can often go back and improve on the first steps. By using an explicit File { settings } inside a class you can assign a sensible set of defaults to all the instances of the same type that lack overriding settings. So we can shorten the previous example to -

File {
  owner => 'whi',
  group => 'whi',
  mode  => 0644,
}

file { '/srv/whi/maps':
  ensure => present,
  source => "puppet://$servername/whi/maps.conf"
}

file { '/srv/whi/elocs':
  ensure => present,
  source => "puppet://$servername/whi/eloc.conf"
}

While this isn’t a huge win in raw characters typed (although in longer manifests they start to mount up) it does move all the common settings in to a single location (keeping us clear of DRY violations) and it leaves only the differences between file type definitions.

You can also apply those kind of settings (such as Exec { path => "path:list" } at the server level by including them in a top level file and then overriding them as needed in each module. If you do this then you need to be aware that any declared type that doesn’t override it gets the global setting, which can lead to the odd action from afar head scratching.