Puppet Module Reusability

Puppet Module Reusability

Presentation from PuppetConf 2013 in San Francisco.

A simple search for "puppet-apache" on GitHub returns 70 separate repositories. An awful lot of people are busy reinventing the same configuration wheel. Configuration management tools promise write once, run anywhere code; but writing code that can be used by anyone looks like a lot of work. This presentation aims to show anyone familiar with Puppet how to write reusable modules and importantly how to make them compatible with already shared modules released on the Forge or elsewhere. We'll look at when and why testing a declarative language is actually useful, examples of good and bad modules and how to re-factor puppet code for re-usability. We'll also talk about potential improvements to Puppet that would make reuse easier.

98234c645fe8c935edc0fec0186d28b8?s=128

Gareth Rushgrove

August 23, 2013
Tweet

Transcript

  1. 5.
  2. 6.
  3. 7.
  4. 9.
  5. 10.
  6. 59.
  7. 68.

    class sample ( ) inherits sample::params { class { 'sample::install':

    } -> class { 'sample::config': } ~> class { 'sample::service': } -> Class['sample'] } Gareth Rushgrove
  8. 69.

    anchor { 'sample::begin': } -> class { 'sample::install': } ->

    class { 'sample::config': } class { 'sample::service': } -> anchor { 'sample::end': } Gareth Rushgrove
  9. 79.

    !"" manifests !"" spec !"" tests !"" templates !"" files

    !"" lib !"" Gemfile Gareth Rushgrove
  10. 80.
  11. 94.

    case $::osfamily { 'Debian': { } 'RedHat', 'Amazon': { }

    default: { fail("${::operatingsystem} not su } Gareth Rushgrove
  12. 101.
  13. 113.

    puppet-lint --with-filename /etc/puppet/modules foo/manifests/bar.pp: trailing whitespace found on line 1

    apache/manifests/server.pp: variable not enclosed in {} on line 56 Gareth Rushgrove
  14. 120.

    context "epel enabled" do let(:params) {{ :epel_enable => true }}

    it { should contain_class('epel') } end Gareth Rushgrove
  15. 121.

    context "epel disabled" do let(:params) {{ :epel_enable => false }}

    it { should_not contain_class('epel') } end Gareth Rushgrove
  16. 129.
  17. 131.

    --- language: ruby before_install: rm Gemfile.lock || true rvm: -

    1.8.7 - 1.9.3 script: bundle exec rake test env: matrix: - PUPPET_VERSION="~> 2.7.0" - PUPPET_VERSION="~> 3.1.0" - PUPPET_VERSION="~> 3.2.0" Gareth Rushgrove
  18. 139.

    it 'should run without errors' do pp = "class {

    'sample': }" puppet_apply(pp) do |r| r.exit_code.should == 2 end end Gareth Rushgrove
  19. 141.

    it 'should run without errors' do pp = "class {

    'sample': }" puppet_apply(pp) do |r| r.exit_code.should == 2 r.refresh r.exit_code.should be_zero end end Gareth Rushgrove
  20. 143.

    it 'should install the erl binary' do shell 'which erl'

    do |r| r.stdout.should =~ /\/usr\/bin\/e r.stderr.should be_empty r.exit_code.should be_zero end end Gareth Rushgrove
  21. 145.

    default_set: 'centos-64-x64' sets: 'centos-64-x64': nodes: "main.foo.vm": prefab: 'centos-64-x64' 'fedora-18-x64': nodes:

    "main.foo.vm": prefab: 'fedora-18-x64' 'debian-607-x64': nodes: "main.foo.vm": Gareth Rushgrove