Fork me on GitHub

Customize Example 42 Puppet Modules

The Example42 Puppet modules share a common logic and structure. There's a module for each application, the module name is also the name of the primary class that installs the software and, if it provides a service, starts it. Generally a base class (placed in a file called init.pp) does not changes configuration files, it just defines their precence (ensure => present), in order to leave easy modifications according to custom needs and logic.
In various modules, though, a configuration file is actually provided and its content is built according to the variables defined for the module.

In every module there's the possibility to autoload a custom "project" class where you can place your customizations, such as defining how to provide the main configuration files (via a template, an array of static files, a concatenation of files or infile line replacements) and adding specific resources, related to the module, that fit your environment.
Consider a Project as a whole Puppet installation, generally managed by the same team. You can have a project for your whole company, or one for each department or also one for each customer, if you manage their servers with Puppet.

So, in order to customize an Example42 module you can:
- If the module already provides configurations that are ok for you, just set the relevant variables and include the module;
- Otherwise, manage all your variations in the dedicated, separated, "project" subclass.

You define your project name with the variable "$my_project". If you set it the module autoloads a class called modulename::$my_project, that is the file MODULEPATH/modulename/manifests/$my_project.pp

If you want to place your custom classes outside the module, just set $my_project_onmodule = "yes" and your custom class will be looked inside a separated module project: MODULEPATH/$my_project/manifests/modulename.pp

The Example42 modules have all sample "example42" classes, that is they work out of the box if you set $my_project="example42". You can rename all the occurrences of the "example42" string with your own project name using the 00_example42scripts/project_rename.sh script. Just run it inside a module and type "example42" at the first prompt, and your $my_module value at the second prompt.

A customization example

Let's consider, for example, the Samba module, which is quite strightforward.
In order to use it you just have to:

include samba

This autoloads the file MODULESPATH/samba/manifests/init.pp where are basically defined 3 resources: the Samba package, the Samba service and the main configuration file.
Note that it's not defined how the file has to be populated (for example with a source => or content => parameter).
At the end of the class there's the code that autoloads the samba::$myproject class where you can place customizations (either in the same module or in a project dedicated one, according to the value of $my_project_onmodule).

By default the MODULESPATH/samba/manifests/example42.pp class (this file is renamed when you launch the project_rename.sh script) is empty:

class samba::example42 {

}

and here you can insert all the custom resources you might want for your Samba setup.
Note that if you need, as probable, to define a way to provide the content of the Samba main configuration file, you must inherit the main class:

class samba::example42 inherits samba {
     File["samba.conf"] {
         source => [ "puppet:///samba/smb.conf-$hostname" ,
                     "puppet:///samba/smb.conf" ],
     }
}

In the above example the resource File["samba.conf"] (note that the resource name is not necessarily the file name) is provided as a static file, which is, by default, $MODULESDIR/samba/files/smb.conf, but can be something like $MODULESDIR/samba/files/smb.conf-hostname for managing exceptions for specific hosts.
You can also decide to manage smb.conf with a template, which uses new user variables you may want to add to the module:

class samba::example42 inherits samba {
     File["samba.conf"] {
         content => template("samba/smb.conf.erb"),
     }
}

in this case the content of smb.conf is generated from the $MODULESDIR/samba/templates/smb.conf.erb template (erb is a Ruby templating system, in a erb file you can use variables and Ruby code).

You may also want to change just some lines in the default configuration file.
Infile line modifications can be done with the native Augeas type or with custom types, and, even if generally not reccomended because we want with Puppet to control the whole configurations and not just parts of them, this can be useful in some specific cases.

In Example42 it has been created a general Type, called Config that can change line or parameters in configuration files using different "engines" (methods to change lines, based on Augeas, sed or other commands).
Many modules in the Example42 provide a custom define to change the main configuration file for the relevant application. They are called modulename::conf, so if you want to change only some parameters on smb.conf you can use the custom define samba::conf:. Note that this is an experimental feature in Example42 modules and it has not been tested widely and is generally unfit to modify configuration files with different parts or directives (as the same smb.conf).

Copyright © 2011 Lab42. Drupal theme by Kiwi Themes.