Puppet: managing directories recursively
This is not very obvious from Puppet's TypeReference, but you can manage directories in a very interesting way:
- Recursively copy a directory from the filestore to a client _and_
- remove all unmanaged files
Still not very interesting, but please see the light:
- You can deploy an empty directory,
- Fill this directory using seperate file resources, possibly from other modules (or even other nodes, if you use exported resources)
- Everything puppet did not put into the directory gets removed.
This yields, very effectively, a fully managed directory with lots of flexibility.
We're using this approach for all sorts of configuration directories, including:
- APT's sources.list.d and apt.conf.d
- Debian-Apache2's sites-available/sites-enabled
- Debian-Exim4's conf.d (including subdirectories)
- Bacula director/Munin configuration (in combination with the concatenated_file type)
For this to work, you need to do a little bit of work:
- prepare a directory in your module filestore which will be the (usually empty) source directory
I often put a README file in there, explaining what's going on.
- add this code snippet for managing the target directory:
file { "/etc/exim4/conf.d":
ensure => directory, # so make this a directory
recurse => true, # enable recursive directory management
purge => true, # purge all unmanaged junk
force => true, # also purge subdirs and links etc.
owner => "root",
group => "root",
mode => 0644, # this mode will also apply to files from the source directory
# puppet will automatically set +x for directories
source => "puppet:///exim/exim4-conf.d-empty",
}
- add one or more file resources which deploy files into the target directory, example:
file { "/etc/exim4/conf.d/router/400_testrouter":
ensure => present,
owner => "root",
group => "root",
mode => 0644,
source => "puppet:///exim/exim4-conf.d/router/400_testrouter",
}
Because puppet looks for those file resources which manage a sub-dir of the managed directory it is also possible to define a sub-directory with unmanaged files, which will then
not get removed - no magic involved here:
file { "/etc/exim4/conf.d/acl":
ensure => directory,
owner => "root",
group => "root",
mode => 0755,
}