Blog
Answers about Puppet
DevOps, Automation
Universe and Everything
Need Puppet help?
Contact Alessandro Franceschi / example42
for direct expert help on Puppet.
If solution is quick, it’s free. No obligations.
Tip of the Week 65 - The example42 Puppet cheat sheet
Yes, we know, there is a famous Puppet cheat sheet available at docs.puppet.com
This is my personal collection of different Puppet DSL items, which I usually generate at each official Puppet Fundamentals training. Now I found the time to paste them into a blog posting and add information on code logic and hiera.
Puppet DSL
Resource type declaration:
type { 'title':
param => 'value',
}
Class definition:
class <name> (
DataType $param1, # this parameter must be provided upon declaration
DataType $param2 = 'value',
) {
# Puppet DSL code
}
Class declaration using a function:
include <name> # no ordering, the mentioned class will be somewhere in the catalog
require <name> # strict ordering, the class must be finished prior continuing
contain <name> # local ordering, the class must be finished within the class where the contain function is used
Class declaration using class as resource type:
class { '<name>':
param1 => 'value',
}
Self defined resource type definition:
define <name> (
DataType $param1,
DataType $param2 = 'value',
){
# Puppet DSL
# all resource type declaration must use the $title variable
# older Puppet code uses $name instead of $title
}
Self defined resource type declaration:
<name> { 'title':
param1 => 'value',
}
Puppet DSL code logic
Case statement:
case $test_variable {
'value1': { # specific value
# Puppet DSL
}
/regexp/: { # regular expression
# Puppet DSL
}
'value2', 'value3': { # multiple values
# Puppet DSL
}
default: { # fall back value - optional
# optional, Puppet DSL
}
}
If statement:
Variant 1: Boolean or existing variable:
if $test_variable {
# Puppet DSL
} else { # else is optional
# Puppet DSL
}
Variant 2: test content of variable:
if $test_variable == 'content' {
# Puppet DSL
}
Variant 3: test content on regular expression:
if $test_variable =~ /regexp/ {
# Puppet DSL
}
Selector:
Please use selectors sparsely as they very fast lead to hard to read Puppet code!
$result_var = $test_var ? {
'value1' => 'return_val1',
'value2' => 'return_val2',
default => 'return_val3',
}
Puppet DSL lambda functions
Iterating over an array:
$var = [ 'element1', 'element2' ]
$var.each |DataType $key| {
type { $key:
param => 'value',
}
}
Iterating over a hash:
$var = {
'key1' => {
'var1' => 'val1',
'var2' => 'val2',
},
'key2' => {
'var1' => 'val1',
},
}
$var.each |DataType $key, DataType $val| {
type { $key:
* => $val,
}
Puppet and Hiera 5
Explicit lookup
class foo {
$data = lookup('key', DataType, <merge behavior>, <default value>)
}
DataType, ‘merge behavior’ and ‘default value’ are optional
merge behavior:
'first' # returns the first occurrence of 'key'
'unique' # returns an array of all occurrences of 'key' with duplicates removed
'hash' # returns a hash of all occurrences of 'key', duplicates hash keys are taken from highest priority
'deep' # returns a hash of all occurrences of 'key', duplicate hash keys are merged
Automatic data lookup
class foo (
DataType $data = 'value' # identical to $data = lookup('foo::data', DataType, 'first', 'value')
) {
}
Puppet will automatically query hiera for the key 'foo::data'
Puppet and Resource ordering
Ordering with meta parameters
Variant 1: require and subscribe
package { 'foo':
ensure => present,
}
file { '/etc/foo/foo.conf':
ensure => file,
require => Package['foo'],
}
service { 'foo':
ensure => running,
subscribe => File['/etc/foo/foo.conf'].
}
Variant 2: before and notify
package { 'foo':
ensure => present,
before =: File['/etc/foo/foo.conf'],
}
file { '/etc/foo/foo.conf':
ensure => file,
notify => Service['foo'],
}
service { 'foo':
ensure => running,
}
Variant 3: resource chaining
package { 'foo':
ensure => present,
}
file { '/etc/foo/foo.conf':
ensure => file,
}
service { 'foo':
ensure => running,
}
Package['foo'] -> File['/etc/foo/foo.conf'] ~> Service['foo']
or multiline:
Package['foo']
-> File['/etc/foo/foo.conf']
~> Service['foo']
Puppet Module
A module is a directory structure inside the $modulepath
.
<modulepath>/
\- <modulename>
|- manifests/
| |- init.pp # main class definition: class <modulename> { ... }
| |- subclass.pp # subclass definition: class <modulename>::subclass { ... }
| \- folder/
| \- subclass.pp # subclass in directory definition: class <modulename>::folder::subclass { ... }
|- files/
| \- staticfile.conf # static file: source => 'puppet:///modules/<modulename>/staticfile.conf',
|- templates/
| \- dynamic_config_file.epp # templated config file: content => epp('<modulename>/dynamic_config_file.epp'),
|- facts.d/
| \- external_facts.yaml # plugin synced
|- types/
| \- datatype.pp # type <modulename>::datatype { ... }
|- functions/
| \- puppetfunction.pp # function <modulename>::puppetfunction { ... }
|- lib/
| |- facter/
| | \- custom_fact.rb # $facts['custom_fact']
| \- puppet/
| |- functions/
| | \- <modulename>/
| | \- puppet4function.rb # Puppet::Functions.create(':<modulename>/puppet4function) do ... end
| |- parser/
| | \- functions/
| | \- puppetfunction.rb # legacy functions - avoid : module Puppet::Parser::Functions.newfunction(':puppetfunction) do ... end
| |- type/
| | \- custom_type.rb # Puppet::Type.newtype(:custom_type) do ... end
| \- provider/
| \- custom_type/
| \- custom_provider.rb # Puppet::Type.type(:custom_type).provider(:custom_provider) do ... end
\- spec/
Happy hacking,
Martin Alfke