Puppet Modules Standards and Interoperability

Opening

Part 1 - Evolution of species

Part 1

First there were recipes...

Then came modules ...

From modules to collections ...

Complete sets of modules

Collections' parallel universes

Complete list on Puppet's wiki

May the Forge be with You!

Puppet Modules Forge

From Caos to Revelation

"Let's put stuff together and see what happens"

 

The road seems clear,
PuppetLabs defines it
We may forge it.

Part 2 - Who Said Standards?

Part 2

Conventions

 

Modules path and structure

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

 

Referring to managed files

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

Modules documentation

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 {
	...
}

Supporting different OS:
Dedicated sub classes

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: { }
    }
}

Supporting different OS:
Centralize internal variables

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",
    }

}

Anatomy of a reusable module

Managing variables and files

Alternatives for managing user variables:

Alternatives for providing configuration files:

Customizing modules

Customization without module modification:

Direct modification of the module:

Part 3 - Example42 proposals

Part 3

www.example42.com

Addressing Interoperability Issues

Extending naming conventions...

Proposed extensions:

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

A general monitor class

A general backup class

More extended classes...

Other extensions (ab)uses:

A convention for inline mods

A generic wrapper for inline mod engines

Puppet for the Masses!

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!

A Mail Server toaster

# 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

Part 4 - Questions and discussions

Part 4

Part ? - Mother nature

Part ?