puppet master hierarchy organization and conventions

April hosts dozens of services on less than ten hardware machines and less than fifty virtual machines. Their configuration is centralized in a puppet master repository. The order of magnitude is not expected to change in the next few years. The hierarchy is organized in manifests and modules. The manifests directory contains the inventory of all virtual machines and bare metal associated with the inclusion of classes and the instantiation of types.

node 'harmine.pavot.vm.april-int',
     'backuppc.novalocal' inherits vserver-pavot {
  include backuppc::server
  include april_nagios::nrpe_server
  include april_nagios::check_backuppc
}

The modules contain the configuration logic for a sub system such as backuppc, screen or ssh.

class screen {
  package { 'screen': ensure => present, }

  file { '/root/.screenrc':
    ensure  => present,
    owner   => 'root',
    group   => 'root',
    mode    => 0400,
    replace => true,
    source  => 'puppet:///screen/.screenrc',
  }

}

Audience

April system administrators are skilled volunteers who can work a few hours at a time. To make the best use of their skills, the hierarchy is organized to minimize the need to understand the whole. A new system administrator should be able to get up to speed within less than one hour.

Manifests

The manifests directory contains the inventory of all virtual machines and bare metal associated with the inclusion of classes and the instantiation of types.
Inheritance is used to reduce the verbosity.

  • The default node ( which is also the one used when nothing else is found for a given puppet client node ) is inherited by all nodes.
  • The vserver-pavot and vserver-ns1 nodes are inherited by all vserver guests residing on the pavot and ns1 hosts, respectively.
    ...
    node 'nginx.pavot.vm.april-int', 'nginx.novalocal' inherits vserver-pavot { }
    node 'bots.pavot.vm.april-int', 'bots.novalocal' inherits vserver-pavot { }
    node 'dns.pavot.vm.april-int', 'dns.novalocal' inherits vserver-pavot { }
    node 'lamp.pavot.vm.april-int', 'lamp.novalocal' inherits vserver-pavot { }
    node 'spamvir.pavot.vm.april-int', 'spamvir.novalocal' inherits vserver-pavot { }
    ...
    
  • The openstack-instance node is inherited by all instance hosted in the OpenStack cluster.
    ...
    node 'jenkins.vm.april-int' inherits openstack-instance { }
    node 'controller.vm.april-int' inherits openstack-instance { }
    node 'april-ci.vm.april-int' inherits openstack-instance { }
    ...
    

The manifests should not contain any logic, only enumerations. For instance, the requirement that the installation of the nagios-server-nrpe is required to add a nagios plugin is found in the april_nagios module. Implementing logic in the manifests would make it more difficult for a new system administrator to understand the structure and figure out where to contribute usefully.

Modules

Third party puppet modules are managed using git submodules. It allows for the inclusion of a specific commit revision of a puppet module published on a git repository. There are other means of distributions for puppet modules but this one was chosen to select the desired set of modules known to work together. The complete list of third party modules is found in the .gitmodules file and managed using the git submodule command.
The puppet modules authored for April are named:

  • april_* ( for instance april_nagios ) when the module implements or relies on April specific logic and conventions.
  • * ( for instance screen ) when the module does not contain any April specific logic.

The module documentation is to be read by someone trying to use the module in the manifests. It does not contain implementation notes or details on the internals. Commented examples are the easiest way to document the intented use:

To monitor a host the april_nagios::host type must be used. It is a wrapper around the nagios_host puppet type.

node 'pavot.april-int' {
  april_nagios::host { 'pavot.april.org': address => '86.65.39.24' }
}

Unit tests for classes are in the classes directory ( i.e. in the april_nagios module classes directory ). The name of the file is the name of the class with :: replaced with _ and _spec.rb appended to it ( i.e. april_nagios::check_backuppc is tested in april_nagios_check_backuppc_spec.rb ). Unit tests for type definitions follow the same conventions and are to be found in the defines directory ( i.e. in the april_nagios module defines directory ).
The files used by the puppet module are placed in the files directory ( i.e. in the april_nagios module files directory ) and referred to as follows:

...
    source  => 'puppet:///april_nagios/contacts_nagios2.cfg',
...

The nagios module

The april_nagios module is related to other puppet modules because it must contain plugins to check the health of the services installed. Each nagios plugin is implemented and tested within the april_nagios module. For instance the backuppc module relies on the april_nagios::check_backuppc class.

class april_nagios::check_backuppc {
  april_nagios::nrpe_plugin { 'check_backuppc':
    user => 'backuppc',
  }
}

The associated test is included in the april_nagios module:

describe 'april_nagios::check_backuppc' do

  context 'when running' do
    it { should contain_file("/etc/nagios/nrpe.d/check_backuppc.cfg").with_ensure('present') }
  end

end

A manfiest using the backuppc class need to include the corresponding april_nagios class. They are related but do not include each other.

node 'harmine.pavot.vm.april-int',
     'backuppc.novalocal' inherits vserver-pavot {
  include backuppc::server
  include april_nagios::nrpe_server
  include april_nagios::check_backuppc
}

The puppet master daemon configuration

The git repository also contains the daemon configuration. The general idea is to be able to re-install the puppet master from scratch using packages and the git repository only. The corresponding files are found at the top level of the git repository and should not be changed.

Confidential information

Confidential informations such as passwords are regrouped in a params.pp file that is not included in the git repository because it is listed in .gitignore. Its structure is exactly as found in the params.pp.sample file. It is imported from the site.pp manifest.
For instance:

class april_params {
 $mysql_nagios_password = 'whatever'
}

will be used from vserver-ns1.pp as follows:

  class { 'april_nagios::check_mysql':
    mysql_nagios_password => $::april_params::mysql_nagios_password
  }

Stages

When applying the puppet manifests on a Debian GNU/Linux squeeze, the apt source list must be updated to include backports

  if $::lsbdistcodename == 'squeeze' {
    apt::source { "squeeze-backports":
      location          => "http://backports.debian.org/debian-backports",
      release           => "squeeze-backports",
      repos             => "main",
    }
  }

so that packages that must be pulled from backports can be found.

 package { 'augeas-lenses/squeeze-backports': ensure => latest, }

Although it would be possible to add a require to make sure one happens before the other, it is more convenient to use puppet stages. The init and first stages are defined in site.pp:

stage { 'first': before => Stage['main'] }
stage { 'init': before => Stage['first'] }

to run before the default stage ( main ). They are used to update the source list and make sure the proper version of the puppet tools are installed before doing anything else in the default.pp manifest:

  class { 'april_apt': stage => init }
  class { 'april_puppet': stage => first }

Licensing

The manifest and modules are licenced under the AGPL and each file must contain the corresponding header. For instance:

#
#    Copyright (C) 2012 Loic Dachary 
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see .
#

One Reply to “puppet master hierarchy organization and conventions”

Comments are closed.