Book Image

Puppet 5 Cookbook - Fourth Edition

By : Thomas Uphill
Book Image

Puppet 5 Cookbook - Fourth Edition

By: Thomas Uphill

Overview of this book

Puppet is a configuration management system that automates all your IT configurations, giving you control of managing each node. Puppet 5 Cookbook will take you through Puppet's latest and most advanced features, including Docker containers, Hiera, and AWS Cloud Orchestration. Updated with the latest advancements and best practices, this book delves into various aspects of writing good Puppet code, which includes using Puppet community style, checking your manifests with puppet-lint, and learning community best practices with an emphasis on real-world implementation. You will learn to set up, install, and create your first manifests with version control, and also learn about various sysadmin tasks, including managing configuration files, using Augeas, and generating files from snippets and templates. As the book progresses, you'll explore virtual resources and use Puppet's resource scheduling and auditing features. In the concluding chapters, you'll walk through managing applications and writing your own resource types, providers, and external node classifiers. By the end of this book, you will have learned to report, log, and debug your system.
Table of Contents (16 chapters)
Title Page
Packt Upsell
Contributors
Preface
Index

Making modules


One of the most important things you can do to make your Puppet manifests clearer and more maintainable is to organize them into modules.

Modules are self-contained bundles of Puppet code that include all the files necessary to implement a thing. Modules may contain flat files, templates, Puppet manifests, custom fact declarations, augeas lenses, and custom Puppet types and providers.

Separating things into modules makes it easier to reuse and share code; it's also the most logical way to organize your manifests. In this example, we'll create a module to manage memcached, a memory caching system commonly used with web applications.

How to do it...

Following are the steps to create an example module:

  1. We will use Puppet's module subcommand to create the directory structure for our new module, in our home directory (/home/vagrant):
[t@cookbook ~]$ puppet module generate thomas-memcached
  1. We need to create a metadata.json file for this module. Please answer the following questions; if the question is not applicable to this module, feel free to leave it blank:
Puppet uses Semantic Versioning (semver.org) to version modules.What version is this module? [0.1.0]-->Who wrote this module? [thomas]-->What license does this module code fall under? [Apache-2.0]-->How would you describe this module in a single sentence?--> A module to install memcachedWhere is this module's source code repository?--> github.com/uphillian/thomas-memcachedWhere can others go to learn more about this module? [https://github.com/uphillian/thomas-memcached]-->Where can others go to file issues about this module? [https://github.com/uphillian/thomas-memcached/issues]-->{"name": "thomas-memcached","version": "0.1.0","author": "thomas","summary": "A module to install memcached","license": "Apache-2.0","source": "github.com/uphillian/thomas-memcached","project_page": "https://github.com/uphillian/thomasmemcached","issues_url": "https://github.com/uphillian/thomas-memcached/issues","dependencies": [{"name": "puppetlabs-stdlib","version_requirement": ">= 1.0.0"}]"data_provider": null}----------------------------------------About to generate this metadata; continue? [n/Y]--> yNotice: Generating module at /home/vagrant/memcached...Notice: Populating templates...Finished; module generated in memcached.memcached/specmemcached/spec/spec_helper.rbmemcached/spec/classesmemcached/spec/classes/init_spec.rbmemcached/metadata.jsonmemcached/manifestsmemcached/manifests/init.ppmemcached/Gemfilememcached/examplesmemcached/examples/init.ppmemcached/README.mdmemcached/Rakefile

This command creates the module directory and creates some empty files as starting points.

  1. Now, edit memcached/manifests/init.pp and change the class definition at the end of the file to the following. Note that the puppet module created many lines of comments; in a production module, you would want to edit those default comments:
class memcached {
  package { 'memcached': ensure => installed, }
  file { '/etc/memcached.conf':
    source  => 'puppet:///modules/memcached/memcached.conf',
    owner   => 'root',
    group   => 'root',
    mode    => '0644',
    require => Package['memcached'],
 }
 service { 'memcached':
   ensure  => running,
   enable  => true,
   require => [Package['memcached'],
               File['/etc/memcached.conf']],
 }
}
  1. Create the modules/thomas-memcached/files directory and then create a file named memcached.conf with the following contents:
[t@cookbook memcached]$ mkdir files
[t@cookbook memcached]$ echo "-m 64 -p 11211 -u nobody -l 127.0.0.1" > files/memcached.conf
  1. We would like this module to install memcached. We'll need to run Puppet with root privileges, and we'll use sudo for that. We'll need Puppet to be able to find the module in our home directory; we can specify this on the command line when we run Puppet, as shown in the following code snippet:
t@cookbook:memcached$ sudo /opt/puppetlabs/bin/puppet apply --modulepath=/home/vagrant -e 'include memcached'Warning: ModuleLoader: module 'memcached' has unresolved dependencies - it will only see those that are resolved. Use 'puppet module list --tree' to see information about modules  (file & line not available)Notice: Compiled catalog for cookbook.strangled.net in environment production in 0.46 secondsNotice: /Stage[main]/Memcached/Package[memcached]/ensure: createdNotice: /Stage[main]/Memcached/File[/etc/memcached.conf]/ensure: defined content as '{md5}febccf4a987759cf4f1558cc625fbea9'Notice: /Stage[main]/Memcached/Service[memcached]/ensure: ensure changed 'stopped' to 'running'Notice: Applied catalog in 6.99 seconds
  1. We can verify that memcached is running using systemctl or puppet resource:
t@cookbook:memcached$ sudo /opt/puppetlabs/bin/puppet resource service memcached
service { 'memcached':
 ensure => 'running',
 enable => 'true',
}
t@cookbook:memcached$ sudo systemctl status memcached
memcached.service - Memcached
  Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; vendor preset: disabled)
  Active: active (running) since Thu 2017-12-28 05:17:41 UTC; 3min 28s ago
Main PID: 4057 (memcached)
  CGroup: /system.slice/memcached.service
          └─4057 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024

Dec 28 05:17:41 cookbook systemd[1]: Started Memcached.
Dec 28 05:17:41 cookbook systemd[1]: Starting Memcached...
Note that /opt/puppetlabs/bin/puppet may not be in root's path, use the full path or add the path to a file in /etc/profile.d. 

How it works...

When we created the module using Puppet's module generate command, we used the name thomas-memcached. The name before the hyphen is your username or your username on Puppet forge (an online repository of modules). Modules have a specific directory structure. Not all of these directories need to be present, but if they are, this is how they should be organized:

modules/
└MODULE_NAME/ never use a dash (-) in a module name
└examples/ example usage of the module
└files/ flat files used by the module
└lib/
  └facter/ define new facts for facter
  └puppet/
    └parser/
      └functions/ define a new puppet function, like sort()
    └provider/ define a provider for a new or existing type
    └util/ define helper functions (in ruby)
    └type/ define a new type in puppet
└manifests/
└init.pp class MODULE_NAME { }
└spec/ rSpec tests
└templates/ EPP or ERB template files used by the module

All manifest files (those containing Puppet code) live in the manifests directory. In our example, the memcached class is defined in the manifests/init.pp file, which will be imported automatically.

Inside the memcached class, we refer to the memcached.conf file:

file { '/etc/memcached.conf':
  source => 'puppet:///modules/memcached/memcached.conf',
}

The preceding source parameter tells Puppet to look for the file in:

MODULEPATH/ (/home/vagrant/)
 └memcached/
   └files/
     └memcached.conf

There's more...

Learn to love modules because they'll make your Puppet life a lot easier. They're not complicated, however; practice and experience will help you judge when things should be grouped into modules, and how best to arrange your module structure. Modules can hold more than manifests and files, as we'll see in the next two sections.

Templates

If you need to use a template as a part of the module, place it in the module's templates directory and refer to it as follows:

file { '/etc/memcached.conf':
  content => epp('memcached/memcached.conf.epp),
}

Puppet will look for the file in:

MODULEPATH/memcached/templates/memcached.conf.epp

Facts, functions, types, and providers

Modules can also contain custom facts, custom functions, custom types, and providers. For more information about these, refer to Chapter 9, External Tools and the Puppet Ecosystem.

Third-party modules

You can download modules provided by other people and use them in your own manifests just like the modules you create. For more on this, see Chapter 7, Using Public Modules.

Module organization

For more details on how to organize your modules, see the puppetlabs website: https://puppet.com/docs/puppet/latest/modules_fundamentals.html.

See also

  • The Creating custom facts recipe in Chapter 9, External Tools and the Puppet Ecosystem
  • The Using public modules recipe in Chapter 9, External Tools and the Puppet Ecosystem
  • The Creating your own resource types recipe in Chapter 9, External Tools and the Puppet Ecosystem
  • The Creating your own providers recipe in Chapter 9, External Tools and the Puppet Ecosystem