Over the last few days I've done quite a lot of work to try and get our puppet configuration up to modern best practises. The Puppet Labs folks strongly encourage you to make as much use of puppet modules as possible. A puppet module gathers together puppet manifests, facter facts and other bits and pieces into a reusable component that you could potentially share with others. Many modules (of very mixed quality) are available on the web, in particular at github and via Puppet Lab's own Forge.

Since version 2.7.14, the puppet command-line tool has built-in support for managing modules:

# puppet module list
/etc/puppet/modules
├── auth (???)
├── interfaces (???)
…
# puppet module install puppetlabs-apt
…

However, they have not provided support for managing modules in puppet manifests themselves. This strikes me as a bit odd: the whole point of using puppet to manage your machines is to capture the configuration in one place. If your configuration depends on a collection of modules and module versions, you'd ideally record that in the puppet configuration itself. Otherwise building a new puppet master is a mixture of manually installing modules and setting it up as a client of your existing master.

Other people to the rescue: Ryan Coleman (and Pieter van de Bruggen) have written puppet_module_provider which does exactly this. (Note that they both work for Puppet Labs). Now I can define which modules and what versions are necessary:

class puppetmaster {
  …
  module { 'rcoleman/puppet_module': ensure => '0.0.3', }
  module { 'puppetlabs/firewall':    ensure => '0.0.4', }
  module { 'puppetlabs/lvm':         ensure => '0.1.1', }
  module { 'puppetlabs/ntp':         ensure => '0.2.0', }
  …

I've decided to pin specific versions given the highly variable nature of module quality. There's no guarantee of backwards compatibility except by reputation of the publisher. The puppetlabs modules are likely to be of higher quality than average, so over time I'll probably gain confidence to change the specific versioning to 'latest' or similar. I also want to double-check how secure the module selection and downloading is (whether it's over HTTPS or cryptographic signatures are checked etc.)