Your SlideShare is downloading. ×
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Puppet: What _not_ to do
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Puppet: What _not_ to do

3,989

Published on

Walter Heck's presentation on "Puppet: what _not_ to do: An interactive journey through the ugly side of Puppet" at Puppet Camp Ghent 2013.

Walter Heck's presentation on "Puppet: what _not_ to do: An interactive journey through the ugly side of Puppet" at Puppet Camp Ghent 2013.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,989
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
27
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Puppet: What_not_ to do? An interactive journey through the ugly sideof Puppet
  • 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 uglyPuppet 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 shouldnt be used, but is there for edge- cases or historical purposes
  • 4. Quiz time! Wake up...
  • 5. == File: modules/ssh/manifests/ssh.ppclass ssh_install { package { ssh: ensure => present }}class ssh_configure { file { /etc/ssh/sshd_config: ensure => present }}
  • 6. == File: modules/ssh/manifests/ssh.ppclass ssh($state = ‘present’ { package { ssh: ensure => $state } file { /etc/ssh/sshd_config: ensure => $state }}# problem: classnames wont be autoloaded, classnames shouldnt have verbs in them,classes should be combined, dont put multiple classes in a file
  • 7. ==schedule { maint: range => 2 - 4, period => daily, repeat => 1,}exec { /usr/bin/apt-get update: schedule => maint,}
  • 8. ==schedule { maint: range => 2 - 4, period => daily, repeat => 1,}exec { /usr/bin/apt-get update: schedule => maint,}# problem: schedule doesnt 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 totrue
  • 11. ==exec { /etc/init.d/apache start: onlyif => ‘ps aux | grep apache | grep -v grep |wc -l’}
  • 12. ==exec { /etc/init.d/apache start: onlyif => ‘ps aux | grep apache | grep -v grep |wc -l’}# problem: this shouldnt be an exec, but aservice
  • 13. ==package { ssh: ensure => present, name => $::operatingsystem ? { Ubuntu => openssh-server, default => ssh, },}
  • 14. ==$sshpkgname = $::operatingsystem ? { Ubuntu => openssh-server, default => undef,}if ($sshpkgname == undef) { fail(‘unsupported OS’)} else { package { ssh: ensure => present, name => $sshpkgname, }}#problem: they encourage behaviour that is not scalable, using default options toassume things, etc.
  • 15. ==case $::operatingsystem { RedHat, CentOS: { file { ‘/etc/httpd/http.conf’: ensure => ‘present’, } } default: { file { ‘/etc/apache2/apache2.conf’: ensure => ‘present’, } }}
  • 16. ==case $::operatingsystem { RedHat, CentOS: { file { ‘/etc/httpd/http.conf’: ensure => ‘present’, } } default: { file { ‘/etc/apache2/apache2.conf’: ensure => ‘present’, } }}#problem: case without default that fails, instead it assumes
  • 17. ==class wordpress { $wordpress_archive = wordpress-3.4.1.zip $apache = $::operatingsystem ? { Ubuntu => apache2, CentOS => httpd, Debian => apache2, default => httpd } $phpmysql = $::operatingsystem ? { Ubuntu => php5-mysql, CentOS => php-mysql, Debian => php5-mysql, default => php-mysql } $php = $::operatingsystem ? { Ubuntu => libapache2-mod-php5, CentOS => php, Debian => libapache2-mod-php5, default => php } package { [unzip,$apache,$php,$phpmysql]: ensure => latest }}
  • 18. ==class wordpress { $wordpress_archive = wordpress-3.4.1.zip $apache = $::operatingsystem ? { Ubuntu => apache2, CentOS => httpd, Debian => apache2, default => httpd } $phpmysql = $::operatingsystem ? { Ubuntu => php5-mysql, CentOS => php-mysql, Debian => php5-mysql, default => php-mysql } $php = $::operatingsystem ? { Ubuntu => libapache2-mod-php5, CentOS => php, Debian => libapache2-mod-php5, default => php } package { [unzip,$apache,$php,$phpmysql]: ensure => latest }}#wordpress class shouldnt touch apache, should be a different module
  • 19. ==$files = [ /etc/mysql, /var/log/mysql,/var/run/mysql ]file { $files: ensure => present, user => mysql, group => mysql, mode => 0755,}
  • 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 testdefined() is (usually) the wrong solution to a resource defined in two locations. It isdangerous, because it only checks if the resource has been defined elsewhere, not withwhat attributes.
  • 23. ==class apache2 {file { /etc/apache2: ensure => directory, require => Service[apache2]}file { /etc/apache2/apache2.conf: ensure => present, require => File[/etc/apache2], notify => Service[apache2],}package { apache2: ensure => present, allowcdrom => true, before => File[/etc/apache2/apache2.conf]}service { apache2: ensure => running, subscribe => File[/etc/apache2/apache2.conf]}}include apache2
  • 24. ==# dependency loopclass apache2 {file { /etc/apache2: ensure => directory, require => Service[apache2]}file { /etc/apache2/apache2.conf: ensure => present, require => File[/etc/apache2], notify => Service[apache2], # <=== The notify metaparameter implies before.}package { apache2: ensure => present, allowcdrom => true, before => File[/etc/apache2/apache2.conf]}service { apache2: ensure => running, subscribe => File[/etc/apache2/apache2.conf] # <=== The subscribe metaparameter impliesrequire.
  • 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 masterclass 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+ filesclass 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.comQuestions? Feel free to get in touch!

×