Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?
description
Transcript of Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?
Can you upgrade to Puppet 4.x?
PuppetCamp Düsseldorf Martin Alfke
About me
• Martin Alfke
• Berlin/Germany
• Freelancer / Trainer
• PuppetLabs Training Partner
• Puppet User Group Berlin
Poll
!
!
• Using Puppet 2.x?
Poll
!
!
• Using Puppet 2.x?
• Using Puppet 3.x?
Agenda
• Why upgrading at all?
• Is your code still working?
• How to upgrading Puppet?
• What brings Puppet 4?
Why do I need to bother?
• Fast releases
• Best Practices
• Changing functionality
• Removing deprecated stuff
• Puppet 4 is coming
Why should I upgrade Puppet at all?
• Do you want security updates?
• Do you want to make use of new functionality? (e.g. automatic data bindings, environmentpath, future parser)
• Do you want to get support (community or enterprise)?
Is my Puppet DSL code still working on new versions?
• Your code was developed some years ago and is still running unmodified
• Your code was written on old best practices and does not follow new style guide
• You do not check your Puppet runs for deprecation warnings (or do you?)
What to look for?
Best practice
• Do you inherit from inherited classes?
• Do you still use import?
• Do you modify remote modules?
• Do you access non-local variables without scope names?
BAD
Best practice
Stop doing multiple levels of inheritance !class foo { } !class foo::bar inherits foo { } !class foo::baz inherits foo::bar { } !class foo::foobar inherits foo::baz { }
BAD
Best practice
Stop doing inheritance at all !class foo { } !class foo::bar inherits foo { } !class foo::baz inherits foo { } !class foo::foobar inherits foo { }
BAD
Best practice
Restrict Inheritance !In most cases you can use parameterised classes instead. Only one kind of inheritance is proven good practice: inherit from module params.pp !class ssh ( $server = $ssh::params::server, $client = $ssh::params::client, $x11fwd = false, ) inherits ssh::params { } !class { ssh::params:: server => false, x11fwd => true, }
BETTER
Best practice
Stop importing !# foo/manifests/init.pp class foo { import ‘bar.pp’ } !# foo/manifests/bar.pp class foo::baz { } !# foo/manifests/baz.pp class foo::baz { } !Which class foo::baz will be used?
BAD
Best practice
Use include !In most cases you can make use of the puppet autoloader and you can use include. !# foo/manifests/init.pp class foo { include foo::baz } !# foo/manifests/baz.pp class foo::baz { } !
BETTER
Best practice
Stop modifying remote modules !Take “remote modules” as a software provided by others. Are you also patching apache?
BAD
Best practice
Co-Work on remote modules !Do a PR if you want improvements. !Keep your remote modules upgradeable.
BETTER
Best practice
Stop using non-local variables without scope !class foo ( $bar = ‘baz’ ) { } !class foo::baz { notify { $bar: } }
BAD
Best practice
Start using non-local variables with scope !class foo ( $bar ) { } !class foo::baz { notify { $foo::bar: } }
BETTER
Best practice
Stop using un-scoped variables in templates !!key = <%= var %> !!!
BAD
Best practice
Start using scoped variables in templates !!key = <%= @var %> !!!!
BETTER
Best practice
Stop using factor variables without top-scope !class foo { notify { “We are on OS: $operatingsystem”: } } !class foo::baz { if $is_virtual { notify { “We are running on $virtual virtualisation”: } } else { notify { “We are running on hardware: $productname”: } }
BAD
Best practice
Start using factor variables with top-scope !class foo { notify { “We are on OS: ${::operatingsystem}”: } } !class foo::baz { if $::is_virtual { notify { “We are running on ${::virtual} virtualisation”: } } else { notify { “We are running on hardware: ${::productname}”: } }
BETTER
Best practice
Stop not doing data validation !class foo ( $server = hiera(‘server’, ‘localhost’) ){ notify { “We will use Server: ${server}”: } } !
BAD
Best practice
Start doing data validation !class foo ( $server = hiera(‘server’, ‘localhost’) ){ # validate_string is a function from stdlib validate_string($server) notify { “We will use Server: ${server}”: } } !
BETTER
Remote modules
• Do foreign modules support your version?
• Newer Puppet versions have new function attributes (arity)
• New foreign module versions might need newer modules not supported by your Puppet version
Remote modules
• Check Puppetfile / metadata.json for requirements
• Test prior upgrading in production
How can I test my actual Puppet DSL code?
How can I test my actual Puppet DSL code?
• Syntax/Semantic check
• puppet parser validate / puppet-syntax / puppet-lint
• Unit test
• rspec-puppet
• Integration test
• beaker, vagrant, serverspec,…
Simple rspec upgrade check
Simple rspec upgrade check
• Add rspec tests to all your modules and run them locally
• Use rvm or rbenv to choose between ruby versions
• Provide puppet version to verify in Gemfile
• Run spec tests locally and verify results
Automatic rspec upgrade check
Automatic rspec upgrade check
• Install a CI-Server (Jenkins, GO, Teamcity,…) and add build steps
• Add git commit hooks to identify changes in repositories
• Run rspec tests automatically
Simple Puppet upgrade test
Simple Puppet upgrade test
• Install Puppet tarball in a separate directory on your master
• Start puppet master manually using RUBYLIB or ruby -I on another port (—masterport 8141)
• Test run from a single node with —noop against the new port
Simple Puppet upgrade test
Example: additional Puppet Master process: !tar zxf puppet-3.7.1.tar.gz -C /opt/puppet-3.7.1 !ruby1.8 -I /opt/puppet-3.7.1/lib /opt/puppet-3.7.1/bin/puppet master \ —nodaemonize —masterport=8150 —pidfile=/tmp/puppetmaster.pid !!Example: Agent run against additional Puppet Master process: !puppet agent —test —masterport 8150
Demo
Puppet 4
• Major update
• Removes deprecated functionality
• New language features
Puppet 4
• Deprecated in Puppet 4:
• node inheritance - use roles/profiles instead
• upper case variable names
• variable with underscore in first position
• references to classes using upper case name/title
• hypens and periods in names
• Ruby DSL
Puppet 4
• New in Puppet 4:
• Strict variable naming and lookup (will become mandatory in Puppet 5)
• Variable type validation
• Boolean conversion (“” -> true instead of false)
• Environmentpath
• Functions in Puppet
• New function API
You can upgrade to Puppet 4.x!
!Thank you.
!Martin Alfke