Talk from Puppet Camp Munich 2013 about how to lay out classes and defines in puppet code, and how to use hiera data.
Covers puppet 2.7 => 3.3 and how to write sanely forwards compatible code between them.
3. Lots of great material
• Still takes effort to understand
• More than one right way to do it
• KISS
• Get data out of manifests
• Follow conventions
http://www.slideshare.net/PuppetLabs/modern-module-development-ken-barber-2012-edinburgh-puppet-camp
http://www.slideshare.net/slideshow/embed_code/25536833
https://speakerdeck.com/player/889a6450ee6b0130026036a0670cc949
4. Modules only!
• No manifests except site.pp
• autoload structure
• Modules work with environments
• Well known higher level reuse patterns! (Later)
All code should be in modules, always - with no exceptions except a site.pp
5. Be flexible!
• Most important for forge modules!
• For your own modules, KISS
• Allow package install to be overridden!
• Allow service to be not managed!
• Don’t manage users!
6. Version compatibility
• Puppet 0.x
• … upgrade?
• Puppet 2.7
• Parameterized classes
• Dynamic scope
• Puppet 3.0
• NO dynamic scope
• Data bindings (automatic hiera)
• Puppet 3.3
• Hiera in modules
http://docs.puppetlabs.com/guides/parameterized_classes.html
15. ARM9 - hiera in modules
• In puppet 3.3:
modules/foo/data
modules/foo/data/common.yaml
modules/foo/data/os/Linux.yaml
modules/foo/hiera.yaml
• Doesn’t really affect design if you did it right!
https://github.com/puppetlabs/armatures/blob/master/arm-9.data_in_modules/index.md
17. Package / File / Service
Most modules do something like this. Note the ${module_name} variable for DRY
http://docs.puppetlabs.com/puppet/3/reference/lang_variables.html#parser-set-variables
http://docs.puppetlabs.com/learning/ordering.html#packagefileservice
19. Package/Config/Service classes
Putting each component in it’s own class makes dependencies simpler / more declarative
http://www.devco.net/archives/2009/09/28/simple_puppet_module_structure.php
20. One entry point
• Entry point should always be init.pp:
include foo
!
http://www.devco.net/archives/2009/09/28/simple_puppet_module_structure.php
21. Externalize dependencies
• Put inter-class dependencies in init.pp
Some people don’t like this (I do), as it makes the dependencies obvious from the entry point you include.
http://www.devco.net/archives/2012/12/13/simple-puppet-module-structure-redux.php
22. Separate parameters
This is the traditional method, having a ::params class. This is good when you have conditional logic around parameters.
http://docs.puppetlabs.com/puppet/3/reference/lang_classes.html#inheritance
http://docs.puppetlabs.com/guides/parameterized_classes.html#appendix-smart-parameter-defaults
23. Hiera parameters (2.7)
For simple (non conditional) values, you can just use a hiera lookup.
If you’re shipping to the forge you still need params class, if you’re not you can just use hiera.
25. Hiera parameter variance
Data in params.pp is kinda gross. Move it out to common.yaml?
Logic for which key to look in can be embedded in the hiera call (instead of params.pp).
26. Hiera parameter variance
If your hierarchy includes:
os/%{::operatingsystem}
common
!
You can just use:
foo::package_name
!
If you have ${::operating_system} in your hierarchy, you can do this simpler thing.
Possible to argue this both ways round, but I’d recommend this as it’s more forward compatible (ARM9)
27. Hiera parameter variance
If your hierarchy includes:
os/%{::operatingsystem}
common
!
You can just use:
foo::package_name
!
Unless it’s a forge module :(
If you’re shipping to the forge, you can’t (sanely) rely on puppet 3.3, and you don’t want to force people to add to
their hieradata - fallback to params.pp
28. Puppet 3.3
Per module hierarchy:
foo/data/os/%{::operatingsystem}.yaml
foo/data/common.yaml
29. Use stdlib
• str2bool
• any2array
• ensure_packages
• ensure_resource
• get_module_path
• getparam
• facts.d
• many many more!
https://github.com/puppetlabs/puppetlabs-stdlib
30. str2bool
• ‘true’ vs true
• All class parameters
• All hiera data
• Other backends may not have
booleans!
https://github.com/puppetlabs/puppetlabs-stdlib
31. any2array
• Any time you take an array parameter!
https://github.com/puppetlabs/puppetlabs-stdlib
35. Multiple instances
• May have more than one nginx running!
• This is where it gets complex :)
• Class or define params override hiera
• Default params in foo::bar
• Instance params:
foo::instance::${instance_name}::bar