Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?

Post on 01-Dec-2014

70 views 1 download

description

PuppetLabs takes care on the Puppet software stack and they provide regular updates of their software. But how about your Puppet DSL code? How can you ensure that your code will also work fine on newer Puppet versions? This talks shows basic steps and actions which should be done to ensure fully functional Puppet DSL code on newer Puppet versions. I will show common old practices, which have been replaced by more modern ways in using Puppet and how to migrate to the new solution. Additionally I want you to learn how you can test your Puppet DSL code prior putting it onto a new Puppet master.

transcript

Can you upgrade to Puppet 4.x?

PuppetCamp Düsseldorf Martin Alfke

<martin.alfke@buero20.org>

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

<martin.alfke@buero20.org>