How to write re-usable puppet definitions?
- by Oliver Probst
I'd like to write a puppet manifest to install and configure an application on target servers.
Parts of this manifest shall be re-usable. Thus I used define for defining my re-usable functionality. Doing so, I've always the problem that there are parts of the definition which are not re-usable.
A simple example is a bunch of configuration files to be created. These file must be placed in the same directory. This directory must be created only once.
Example:
nodes.pp
node 'myNode.in.a.domain' {
mymodule::addconfig {'configfile1.xml':
param => 'somevalue',
}
mymodule::addconfig {'configfile2.xml':
param => 'someothervalue',
}
}
mymodule.pp
define mymodule::addconfig ($param) {
$config_dir = "/the/directory/"
#ensure that directory exits:
file { $config_dir:
ensure => directory,
}
#create the configuration file:
file { $name:
path => "${config_dir}/${name}"
content => template('a_template.erb'),
require => File[$config_dir],
}
}
This example will fail, because now the resource file {$config_dir: is defined twice.
As far as I understood, it is required to extract these parts into a class. Then it looks like this:
nodes.pp
node 'myNode.in.a.domain' {
class { 'mymodule::createConfigurationDirectory':
}
mymodule::addconfig {'configfile1.xml':
param => 'somevalue',
require => Class ['mymodule::createConfigurationDirectory'],
}
mymodule::addconfig {'configfile2.xml':
param => 'someothervalue',
require => Class ['mymodule::createConfigurationDirectory'],
}
}
But this makes my interface hard use. Every user of my module has to know, that there is a class which is additionally required.
For this simple use case the additional class might be acceptable. But with growing module complexity (lots of definitions) I'm a bit afraid of confusing the modules user.
So I'd like to know is there a better way to handle this dependencies. Ideally, classes like createConfigurationDirectory are hidden from the user of the modules api.
Or are there some other "Best Practices"/Patterns handling such dependencies?