Puppet 4 introduces significant changes including improved performance, scalability, measurability and flexibility. It features a new Puppet Server and packaging, enhanced environments, r10k for managing environments from git, new language features like lambdas and EPP templating, stronger data typing, and deprecation of features like node inheritance. Upgrading requires testing and supporting modules for compatibility with the breaking changes in Puppet 4.
12. Benefits
All environments in one place
Per environment configuration (environment.conf)
config_version = '/usr/bin/git --git-dir /etc/puppet/environments/
$environment/.git rev-parse HEAD'
Newly added environments are available immediately
15. Lambdas
Lambda
“a block of code that has parameters and can be invoked/called with arguments. A
single lambda can be passed to a function”
$a = [1,2,3]
each($a) |value| {notice $value }
16. Lambdas and functions
each - iterating over an array
map - transform an array or hash into a new array
filter - filters an array or hash
reduce - reduces an array or hash to a single value
slice - slices an array or hash into chunks
17. Using functions
Standard Puppet way:
function_name(argument) - each($variable)
Ruby way - chaining
argument.function_name - $variable.each
18. EPP Template engine
Use Puppet $var instead of Ruby @var
epp(filename)
inline_epp(epp_string)
19. HEREDOC support
Like Shell HEREDOC
$multiline_text = @(EOF)
# Managed by Puppet
intended two spaces
starting at beginning of line
| intention starts at pipe sign
EOF
20. HEREDOC control character
- prevents a new line (like erb/epp)
@(“EOF”) - variable substition
@(EOF/tn) - enables char escapes
availabe char escapes: t,s,r,n,u,L,$
Default to off
21. Puppet 4.0 Data Bindings
New “hierarchy”:
global data (hiera)
data in environment (environment.conf)
data in modules
23. Why do we need types?
class ssh (
$server = true,
) {
if $server {
include ssh::server
}
}
Parameterized class with parameter default
24. Why do we need types?
class ssh (
$server = true,
) {
if $server {
include ssh::server
}
}
!
!
class { ‘ssh’:
server => ‘false’,
}
!
!
!
!
!
!
!
!
!
Usage of parameterised class. But: string
instead of boolean !
25. Why do we need types?
class ssh (
$server = true,
) {
if validate_bool($server) {
include ssh::server
}
}
!
!
class { ‘ssh’:
server => ‘false’,
}
Parameterized class with parameter default
!
!
Now with data validation (from stdlib)
26. Why do we need types?
users::hash:
‘tom’:
gid: ‘123’
home: ‘/home/tom’
managehome: false
‘ben’:
gid: ‘124’
home: /home/ben
managehome: ‘true’
‘tim’:
gid: 0125
home: ‘home/tim’
managehome: ‘false’
But: how to deal with more complex data?
!
!
Do you see the errors?
27. Why do we need types?
users::hash:
‘tom’:
gid: ‘123’
home: ‘/home/tom’
managehome: false
‘ben’:
gid: ‘124’
home: /home/ben
managehome: ‘true’
‘tim’:
gid: 0125
home: ‘home/tim’
managehome: ‘false’
But: how to deal with more complex data?
!
!
!
!
!
!
Missing quotes
String instead of bool
!
Missing quotes and leading 0
Missing trailing slash
String instead of bool
28. We need types!
class ssh (
Boolean $server = true,
) {
if $server {
include ssh::server
}
}
!
Types, Types, Types, Types
29. We need types!
class ssh (
Boolean $server = true,
) {
if $server {
include ssh::server
}
}
!
!
class { ‘ssh’:
server => ‘false’,
}
!
Error 400 on SERVER: Expected parameter 'server' of
'Class[Ssh]' to have type Boolean, got String
!
!
!
!
!
!
!
!
!
We now get proper error messages.
33. Node Inheritance
node ‘basenode’ {
include base
include security
}
!
node ‘www.server.com’ inherits basenode {
include webserver
}
# Dummy node as default
!
!
!
!
# Real node inherits from basenode
34. Roles & Profiles
node ‘www.server.com’ {
include webserver
}
!
!
class basenode {
include base
include security
}
!
class webserver {
include basenode
}
# No more node inheritance
!
!
!
!
# Define a class instead
36. Empty string comparison
$message = ‘’
!
if $message {
notify { “Message: ${message}”: }
}
Empty string set as default
!
Check for variable existing and having
content
37. Empty string comparison
$message = ‘’
!
if $message and $message != ‘’ {
notify { “Message: ${message}”: }
}
Empty string set as default
!
Check for variable existing and not empty
string
38. Variable naming
A variable may not start with
a capital letter
an underscore (well. yes. it may. but. it’s private.)
39. Reference Naming
Reference deprecation
capital letter on title
empty space between Type reference and title
!
Class [Ssh]
!
Class [‘ssh’]
!
Class[‘ssh’]
!
Deprecated capital title
!
Empty space
!
Working
42. Ruby DSL
Puppet Ticket #18876
Closed 02/04/2013
New Ruby DSL API was revamped: “the number and
severity of issues that came up in exploratory testing
led us to the conclusion that it was not supportable
code” - Puppet Dev ML - 01/26/2013
hostclass ‘ssh’ do
end
43. More deprecation
Relative resolution of class names - the reason why
you want to use double colon - include ::ssh
Importing manifests
Matching numbers with regexp
Search function
Mutating arrays and hashes