Thinking through puppet code layout

Preview:

DESCRIPTION

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.

Citation preview

Thinking through code layout - Tomas Doran

@bobtfish

tdoran@yelp.com

28/11/2013

• Still takes effort to understand

•More than one right way to do it

• KISS

• Get data out of manifests

• Follow conventions

Lots of great material

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

• No manifests except site.pp

• autoload structure

•Modules work with environments

•Well known higher level reuse patterns! (Later)

Modules only!

All code should be in modules, always - with no exceptions except a site.pp

•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!

Be flexible!

• 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

Version compatibility

http://docs.puppetlabs.com/guides/parameterized_classes.html

Dynamic scope

Dynamic scope

NO Dynamic scope

Data binding

Puppet 2.7

Data binding

Puppet 2.7

Puppet 3.x

ARM9

ARM9

?????

Eh? Is that a processor type?

ARM9

Or one of these?

• 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!

ARM9 - hiera in modules

https://github.com/puppetlabs/armatures/blob/master/arm-9.data_in_modules/index.md

Package / File / Service

Starting at the basics….

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

Metaparameters

http://docs.puppetlabs.com/learning/ordering.html#packagefileservice

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

• Entry point should always be init.pp: include foo

One entry point

!http://www.devco.net/archives/2009/09/28/simple_puppet_module_structure.php

• Put inter-class dependencies in init.pp

Externalize dependencies

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

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

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.

Hiera parameters (3.x)

http://docs.puppetlabs.com/puppet/3/reference/lang_classes.html#inheritance http://docs.puppetlabs.com/guides/parameterized_classes.html#appendix-smart-parameter-defaults

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).

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)

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

Puppet 3.3

Per module hierarchy: foo/data/os/%{::operatingsystem}.yaml foo/data/common.yaml

• str2bool • any2array • ensure_packages • ensure_resource • get_module_path • getparam • facts.d •many many more!

Use stdlib

https://github.com/puppetlabs/puppetlabs-stdlib

• ‘true’ vs true • All class parameters • All hiera data

• Other backends may not have booleans!

str2bool

https://github.com/puppetlabs/puppetlabs-stdlib

• Any time you take an array parameter!

any2array

https://github.com/puppetlabs/puppetlabs-stdlib

!

• Avoids duplicate resources

!!!

• Same for generic resources

ensure_packages / ensure_resource

https://github.com/puppetlabs/puppetlabs-stdlib

• nginx::vhost {} • docker::run {}

Toolkits

• nginx::vhost {} • docker::run {}

• create_resources helper

Toolkits

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

Toolkits + Multiple instances

getparam (stdlib)

https://github.com/puppetlabs/puppetlabs-stdlib

Toolkits + Multiple instances

• Role = node classifier (contains >= 1 profile) • role::webserver

• Profile = use multiple modules + hiera data • profile::apache • profile::tomcat

•Module = Single concern • apache • tomcat

Roles and profiles

http://www.craigdunn.org/2012/05/239/ http://blog.keepingyouhonest.net/?p=443 https://puppetlabs.com/learn/roles-profiles-introduction

tags for overriding

http://docs.puppetlabs.com/puppet/3/reference/lang_resources.html#amending-attributes-with-a-collector

Thanks!

$864

http://www.yelp.com/careers?jvi=ogVTXfwL

Questions?

Slides will be up shortly at:

http://slideshare.net/bobtfish/

Mail: tdoran@yelp.com

Twitter: @bobtfish

Recommended