Puppet classes versus modules

“So why use modules? Well, if the application, daemon, or function you are configuring contains multiple classes, files, and/or templates, the easiest way to package these resources is to modularize them. Modules make management of configuration collections easier and more structured.”

— from book “Pulling Strings with Puppet

Modules appear to mainly be a way to group multiple files and resources for an application.  Modules require a longer folder path than classes do:




The only downside I can see for modules is more typing into longer paths, and de-centralization of files. It seems more practical (to me, at this point) to have all the masterfiles for all classes under /etc/puppet/files in case someone else needs to easily update them. But best practices strongly encourage use of modules, so…

What to add to site.pp to enable module:

import "mysql"

node default {
  include mysql

When referring to the fileserver source for the init.pp config file, in this example, mysql’s my.cnf, you can change the way the file is called:


source => "puppet:///files/my.cnf"

change to:


source => "puppet:///mysql/my.cnf"

A module’s init.pp appears to be the same as a class .pp file, except for the source path.

Postfix module: (based on example in “Pulling Strings with Puppet”)
# Copy all required postfix files, run newaliases if /etc/aliases has changed, and restart postfix last.
class postfix {

$packagelist = ["postfix.$architecture"]
package {$packagelist: ensure => installed"}

postfix::postfix_files {

       mode   => "640",
       source => "aliases";

       source => "main.cf";

       source => "master.cf";

       source => "canonical"

# Ensure that the postfix service is installed and running.
#  Restart the service if main.cf changes.

service { "postfix":
       enable  => "true",
       ensure  => "running",
       restart => true,
       require => Package["postfix.$architecture"],
       subscribe => File["/etc/postfix/main.cf"],

# Define some variables that will apply to all of the files

define postfix::postfix_files($owner = root, $group = root, $mode = 644,
$source, $backup = false, $recurse = false, $ensure = file) {

    file { $name:
      mode   => $mode,
      owner   => $owner,
      group   => $group,
      backup  => $backup,
      recurse => $recurse,
      ensure  => $ensure,
      require => Package["postfix.$architecture"],
      source  => "puppet:///postfix/$source"

# Rerun newaliases and restart postfix if aliases updated:
exec {newaliases: command => "/usr/sbin/postalias /etc/aliases ; service postfix restart",
	subscribe => File["/etc/aliases"],
	refreshonly => true,

Some more examples of Puppet classes

class for ldconfig and ld.so.conf:

# /etc/puppet/manifests/classes/ldconfig.pp
class ldconfig {
    file { "/etc/ld.so.conf":
        owner   => root,
        group   => root,
        mode    => 644,
        source  => "puppet:///files/ld.so.conf",
# rerun ldconfig if the .conf file has changed
exec { ldlibcfg: command => "/sbin/ldconfig",
    subscribe => File["/etc/ld.so.conf"],
    refreshonly => true


# /etc/puppet/manifests/classes/snmpd.pp# 
class snmpd {
    file { "/etc/snmp/snmpd.conf":
        owner   => root,
        group   => root,
        mode    => 644,
        source  => "puppet:///files/snmpd.conf",
# Copy snmpd.options to reduce snmp logging noise
    file { "/etc/sysconfig/snmpd.options":
        owner   => root,
        group   => root,
        mode    => 755,
        source  => "puppet:///files/snmpd.options",
        require => File["/etc/snmp/snmpd.conf"],
# Restart snmpd service only if file has changed
exec { snmpd_restart: command => "/etc/init.d/snmpd restart",
    subscribe => File["/etc/snmp/snmpd.conf"],
    refreshonly => true