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

Using selectors and case statements


Although you could write any conditional statement using if, Puppet provides a couple of extra forms to help you express conditionals more easily: the selector and the case statement.

How to do it...

Here are some examples of selector and case statements:

  1. Add the following code to your manifest:
$systemtype = $::operatingsystem ? {
  'Ubuntu' => 'debianlike',
  'Debian' => 'debianlike',
  'RedHat' => 'redhatlike',
  'Fedora' => 'redhatlike',
  'CentOS' => 'redhatlike',
  default  => 'unknown',
}
notify { "You have a ${systemtype} system": }
  1. Add the following code to your manifest:
class debianlike {
  notify { 'Special manifest for Debian-like systems': }
}
class redhatlike {
  notify { 'Special manifest for RedHat-like systems': }
}
case $::operatingsystem {
  'Ubuntu', 'Debian': { include debianlike },
  'RedHat', 'Fedora', 'CentOS', 'Springdale': { include redhatlike }
  default: { notify { "I don't know what kind of system you have!": } }
}

How it works...

Our example demonstrates both the selector and the case statement, so let's see in detail how each of them works.

Selector

In the first example, we used a selector (the ? operator) to choose a value for the $systemtype variable depending on the value of $::operatingsystem. This is similar to the ternary operator in C or Ruby, but instead of choosing between two possible values, you can have as many values as you like.

Puppet will compare the value of $::operatingsystem to each of the possible values we have supplied in Ubuntu, Debian, and so on. These values could be regular expressions (for example, for a partial string match or to use wildcards), but in our case, we have just used literal strings.

As soon as it finds a match, the selector expression returns whatever value is associated with the matching string. If the value of $::operatingsystem is fedora, for example, the selector expression will return the redhatlike string and this will be assigned to the $systemtype variable.

Case statement

Unlike selectors, the case statement does not return a value. Case statements come in handy when you want to execute different code depending on the value of an expression. In our second example, we used the case statement to include either the debianlike or redhatlike class, depending on the value of $::operatingsystem.

Again, Puppet compares the value of $::operatingsystem to a list of potential matches. These could be regular expressions or strings, or as in our example, comma-separated lists of strings. When it finds a match, the associated code between curly braces is executed. So, if the value of $::operatingsystem is Ubuntu, then the code including debianlike will be executed.

There's more...

Once you've got a grip on the basic use of selectors and case statements, you may find the following tips useful.

Regular expressions

As with if statements, you can use regular expressions with selectors and case statements, and you can also capture the values of the matched groups and refer to them using $1, $2, and so on:

case $::lsbdistdescription {
  /Ubuntu (.+)/: {
    notify { "You have Ubuntu version ${1}": }
  }
  /CentOS (.+)/: {
    notify { "You have CentOS version ${1}": }
  }
  default: {}
}

Defaults

Both selectors and case statements let you specify a default value, which is chosen if none of the other options match (the style guide suggests you always have a default clause defined):

$lunch = 'Filet mignon.' $lunchtype = $lunch ? {
  /fries/ => 'unhealthy',
  /salad/ => 'healthy',
  default => 'unknown',
}
notify { "Your lunch was ${lunchtype}": }

The output is as follows:

t@cookbook:~$ puppet apply lunchtype.pp
Notice: Compiled catalog for cookbook.strangled.net in environment production in 0.01 seconds
Notice: Your lunch was unknown

When the default action dosen't occur, use the fail() function to halt the Puppet run.