Complete sets of modules
Complete list on Puppet's wiki
Puppet Modules Forge
"Let's put stuff together and see what happens"
The road seems clear,
PuppetLabs defines it
We may forge it.
Where to place modules:
[root@localhost ~]# puppetmasterd --genconfig | grep modulepath modulepath = /etc/puppet/modules:/usr/share/puppet/modules
How files are organized in a module:
$modulepath/
downcased_module_name/
tests/
init.pp
files/
manifests/
init.pp
lib/
puppet/
parser/
functions
provider/
type/
facter/
templates/
metadata.json
README
Notes:
- lib was plugins on Puppet < 0.25
- depends/ directory is obsolete
Static source files or templates:
class autofs::client {
package { autofs: ensure => latest }
service { autofs: ensure => running }
file { "/etc/auto.homes":
source => "puppet://$servername/modules/autofs/auto.homes"
}
file { "/etc/auto.master":
content => template("autofs/auto.master.erb")
}
}
Sourced files are searched in:
$modulepath/autofs/files/auto.homes
Templates are searched in:
$templatedir/autofs/auto.master.erb
$modulepath/autofs/templates/auto.master.erb
Puppetdoc generates documentation from manifests comments:
$ puppetdoc [--all] --mode rdoc [--outputdir] [--debug|--verbose] [--trace] [--modulepath ] [--manifestdir ] [--config ]
Comment classes as below:
# Class: apache
#
# This module manages Apache
#
# Parameters:
#
# Actions:
#
# Requires:
#
# Sample Usage:
#
# [Remember: No empty lines between comments and class definition]
class apache {
...
}
Minor differences can be managed in the same class:
class apache {
[...]
package { apache:
name => "${apache::params::packagename}",
ensure => present,
}
}
Major differences are managed in dedicated (autoloaded) classes:
class apache {
[...]
case $operatingsystem {
debian: { include apache::debian }
ubuntu: { include apache::debian }
default: { }
}
}
A class where to place all the internal variables of a module::params
class apache::params {
$packagename = $operatingsystem ? {
freebsd => "apache20",
debian => "apache2",
ubuntu => "apache2",
default => "httpd",
}
$servicename = $operatingsystem ? {
debian => "apache2",
ubuntu => "apache2",
default => "httpd",
}
$username = $operatingsystem ? {
debian => "www-data",
ubuntu => "www-data",
default => "apache",
}
$configfile = $operatingsystem ?{
freebsd => "/usr/local/etc/apache20/httpd.conf",
ubuntu => "/etc/apache2/apache2.conf",
debian => "/etc/apache2/apache2.conf",
default => "/etc/httpd/conf/httpd.conf",
}
$configdir = $operatingsystem ?{
freebsd => "/usr/local/etc/apache20",
ubuntu => "/etc/apache2",
debian => "/etc/apache2",
default => "/etc/httpd/conf",
}
$documentroot = $operatingsystem ?{
debian => "/var/www",
ubuntu => "/var/www",
suse => "/srv/www",
default => "/var/www/html",
}
}


Alternatives for managing user variables:
Alternatives for providing configuration files:

Customization without module modification:
Direct modification of the module:

Proposed extensions:
(This is a call for standardization: first we should agree on needs, then on naming)

class postfix::monitor {
include postfix::params
monitor::port { "port_tcp_25":
proto => "tcp",
port => 25,
enable => true,
}
monitor::port { "port_tcp_465":
proto => "tcp",
port => 465,
enable => false,
}
monitor::process { "postfix_process":
name => "${postfix::params::processname}",
enable => true,
}
monitor::plugin { "postfix_plugin":
name => "${postfix::params::plugin}",
enable => false,
}
}

class apache::backup {
include apache::params
backup { "apache_data":
frequency => daily,
path => "${apache::params::documentroot}",
enabled => true,
host => $fqdn,
}
backup { "apache_logs":
frequency => daily,
path => "${apache::params::logs}",
enabled => false,
host => $fqdn,
}
}

Other extensions (ab)uses:

define sysctl::conf ($value) {
require sysctl::params
config { "sysctl_conf_${name}":
file => "${sysctl::params::configfile}",
parameter => "${name}",
value => "${value}",
engine => "augeas",
notify => Exec["sysctl -p"],
}
}

define config (
$file='',
$line='',
$pattern='',
$parameter='',
$value='',
$engine='',
$source='default',
$lens='IniFile'
) {
case $engine {
augeas: {
augeas {
"Config_augeas_$file-$parameter":
context => "/files$file",
changes => "set $parameter $value",
# onlyif => "get $parameter != $value",
}
}
file2augeas: {
file2augeas {
"Config_file2augeas_$file-$parameter":
file => "$file",
parameter => "$parameter",
value => "$value",
lens => "$lens",
}
}
line: {
line {
"Config_line_$file-$line":
file => "$file",
line => "$line",
ensure => "present",
source => "$source",
}
}
replaceline: {
replaceline {
"Config_replaceline_$file-$line":
file => "$file",
pattern => "$pattern",
replacement => "$line",
}
}
default: {
# You may define a default
}
}
}

Exploring methods to make Puppet useful also to who...
..
does not really need it ...
... or has no intention to learn and use it.
One Shot Puppet runs for prototypes and appliances:
Integrate in your Puppet modules or Run Once and forget!

# Postfix + Mysql + Dovecot + MailScanner + Mailwatch + Clamav + SpamAssassin
# Example42 toaster (Variables and classes can be included via an external tool)
# Variables to set and customize (and hide, when secret)
$postfix_mysqluser = "postfix"
$postfix_mysqlpassword = "example42"
$postfix_mysqlhost = "localhost"
$postfix_mysqldbname = "postfix"
$postfix_mynetworks = "10.42.0.0/16, 127.0.0.1/32"
$mailscanner_mysqluser = "mailwatch"
$mailscanner_mysqlpassword = "example42"
$mailscanner_mysqlhost = "localhost"
$mailscanner_mysqldbname = "mailscanner"
$mailscanner_adminuser = "admin"
$mailscanner_adminpassword = "admin"
# General setups
Exec { path => "/bin:/sbin:/usr/bin:/usr/sbin" }
import "common"
# Toaster components
include mysql
include sendmail::disable
include postfix::postfixadmin
include dovecot::mysql
include mailscanner::mailwatch
include clamav
include squirrelmail