2. •Walter Heck, Founder of OlinData
•2,5 years experience with Puppet in 5+
different environments
•Experienced Puppet Fundamentals trainer
•Had my eyes bleed many times with ugly
Puppet code
3. • Design mistakes
might not be glaringly obvious or even
wrong at first, but will cause trouble later
• Language mistakes
Puppet provides functionality that
shouldn't be used, but is there for edge-
cases or historical purposes
8. ==
schedule { 'maint':
range => '2 - 4',
period => daily,
repeat => 1,
}
exec { '/usr/bin/apt-get update':
schedule => 'maint',
}
# problem: schedule doesn't mean something will execute, a common pitfall.
If there is no puppet run between these hours, the apt-get exec will not be run
9. ==
$myvar = ‘false’
if ($myvar) {
notice(‘this is true’)
} else {
notice(‘This is false’)
}
10. ==
$myvar = ‘false’
if ($myvar) {
notice(‘this is true’)
} else {
notice(‘This is false’)
}
#problem: 'false' evaluates to
true
12. ==
exec { '/etc/init.d/apache start':
onlyif => ‘ps aux | grep apache | grep -v grep |
wc -l’
}
# problem: this shouldn't be an exec, but a
service
20. ==
#arrays of resources are not wrong, but dangerous.
file { '/etc/mysql':
ensure => present,
user => mysql,
group => mysql,
mode => 0700, <=== careful with this!
}
file { '/var/log/mysql':
ensure => present,
user => mysql,
group => mysql,
mode => 0755,
}
file { '/var/run/mysql':
ensure => present,
user => mysql,
group => mysql,
mode => 0755,
}
21. ==
if defined(File['/tmp/foo']) {
notify('This configuration includes the /tmp/foo file.')
} else {
file {'/tmp/foo':
ensure => present,
}
}
22. ==
class test {
if defined(File['/tmp/foo']) {
notice('This configuration includes the /tmp/foo file.')
} else {
file {'/tmp/foo':
ensure => present,
group => root
}
}
if defined(File['/tmp/foo']) {
notice('This configuration includes the /tmp/foo file.')
} else {
file {'/tmp/foo':
ensure => present,
group => puppet
}
}
}
include test
defined() is (usually) the wrong solution to a resource defined in two locations. It is
dangerous, because it only checks if the resource has been defined elsewhere, not with
what attributes.
25. class test {
file { '/tmp/somefile.txt':
ensure => 'file',
mode => 0600,
owner => 'root',
group => 'root',
source => '/etc/puppet/modules/test/somefile.txt'
}
}
include test
26. ==
# use puppet:///modules/ instead of the full path on the puppet master
class test {
file { '/tmp/somefile.txt':
ensure => 'file',
mode => 0600,
owner => 'root',
group => 'root',
source => 'puppet:///modules/test/somefile.txt'
}
}
include test
27. ==
class test {
file {‘/tmp/large/dir/with/many/subdirs/and/many/files’:
ensure => present,
owner => root,
group => root,
recurse => true
}
}
include test
28. ==
# do not use recurse => true on a dir with over 100+ files
class test {
file {‘/tmp/large/dir/with/many/files’:
ensure => present,
owner => root,
group => root,
recurse => true
}
}
include test
# alternative :’(
class test {
exec {'/bin/chown -R root:root /tmp/large/dir/with/many/files':
}
}
29. Walter Heck - OlinData
Email: walterheck@olindata.com
Twitter: @walterheck / @olindata
Web: http://olindata.com
Questions? Feel free to get in touch!