Statements
Getting started
Conditional statements allow you to write Puppet code that will return different values or execute different blocks of code depending on conditions you specify. In conjunction with Facter, which makes details of a machine available as variables, this lets you write Puppet code that flexibly accommodates different platforms, operating systems, and functional requirements.
Factor
Factor is a Puppet build-in tool, which is cross-platform system profiling library. It discovers and reports all the key attributes of you system. it ships with Puppet Agent, that means all the all the Puppet node has this build-in tool.
How to use Factor, there are two ways:
Command Line
In Command line, factor
is a handy tool to profiling your system, for example you can use factor to check you ip address:
factor ipaddress
Which would directly tell what's the ip address.
To check the linux distribution:
factor operatingsystem
This would directly tell you what's distribution this machine it is. Normally, to get this info, we need to use uname -a
or some other command to check the linux distribution, but as factor is cross-platform, command is consistent to profile the same attribute.
For all core facts, please refer to Puppet Core Facts documentation.
Manifest
It's pretty handy to use factor in command line, but because facts for a node are available in any manifest compiled for that node, they exist somewhere called top scope. This means that though a fact can be accessed anywhere, it can also be overwritten by any variable of the same name in a lower scope (e.g. in node or class scope). To avoid potential collisions, it's best to explicitly scope references to facts. You specify top scope by prepending your factname with double colons :: (pronounced "scope scope"). So a fact in your manifest should look like this: $::factname
So if you want to refer ipaddress or operatingsystem, in Puppet manifest you can simply refer it like this:
if $::ipaddress == '10.154.10.111' {
$groups = 'wheel'
}
elsif $::operatingsystem == 'debian' {
$groups = 'admin'
}
Conditions
Conditional statements return different values or execute different blocks of code depending on the value of a specified variable. This is key to getting your Puppet modules to perform as desired on machines running different operating systems and fulfilling different roles in your infrastructure.
Puppet supports a few different ways of implementing conditional logic:
if
statements,unless
statements,case
statements, and- selectors.
if
and unless
This is simple enough, unless
is the reversed if
statement like it has in Ruby, and if you have may if statement, then you can add elsif
as well.
Case
Like if statements, case statements choose one of several blocks of Puppet code to execute. Case statements take a control expression, a list of cases, and a series of Puppet code blocks that correspond to those cases. Puppet will execute the first block of code whose case value matches the control expression.
A special default case matches anything. It should always be included at the end of a case statement to catch anything that did not match an explicit case. While your other cases will often be strings with surrounding quotation marks, the default case is a bare word without surrounding quotation marks.
For instance, if you were setting up an Apache webserver, you might use a case statement like the following:
case $::operatingsystem {
'CentOS': { $apache_pkg = 'httpd' }
'Redhat': { $apache_pkg = 'httpd' }
'Debian': { $apache_pkg = 'apache2' }
'Ubuntu': { $apache_pkg = 'apache2' }
default: { fail("Unrecognized operating system for webserver.") }
}
package { $apache_pkg :
ensure => present,
}
This would allow you to always install and manage the right Apache package for a machine's operating system. Accounting for the differences between various platforms is an important part of writing flexible and re-usable Puppet code, and it's a paradigm you will encounter frequently in published Puppet modules.
Selector
Selector statements are similar to case statements, but instead of executing a block of code, a selector assigns a value directly. A selector might look something like this:
$rootgroup = $::osfamily ? {
'Solaris' => 'wheel',
'Darwin' => 'wheel',
'FreeBSD' => 'wheel',
'default' => 'root',
}
Here, the value of the $rootgroup
is determined based on the control variable $::osfamily
. Following the control variable is a ?
(question mark) symbol. In the block surrounded by curly braces are a series of possible values for the $::osfamily
fact, followed by the value that the selector should return if the value matches the control variable.
Because a selector can only return a value and cannot execute a function like fail()
or warning()
, it is up to you to make sure your code handles unexpected conditions gracefully. You wouldn't want Puppet to forge ahead with an inappropriate default value and encounter errors down the line.