Reusable Cookbook Patterns

Post on 21-May-2015

1.074 views 5 download

Tags:

description

From Chef Summit 2013

Transcript of Reusable Cookbook Patterns

Cookbook ReusabilityNoah Kantrowitz

Balanced, Inc

The problem

Community cookbooks only do 90% of what you need.

New Problem

•Proliferation of special cases.

•Complex contribution process.

•Forking during iteration.

Wrapper Cookbooks

•Extension by prepend/append.

•Overriding attributes.

•chef-rewind, here be dragons.

Requirements

•Responsive effort: 5% change ⇒ ~5% work

•Documented extension mechanism.

•Integration with kitchen, berks, etc.

DevOps

LWRPs?

•Better, but not by much.

•Still only prepend/append.

•No substitution except rewind.

Enter: Classesclass Chef class Resource::Something < Resource ... end class Provider::Something < Provider ... endend

Chef::Resourcedef initialize(*args) super @resource_name = :something @action = :enable @allowed_actions = [ :enable, :disable ]end

Chef::Resource

def path(arg=nil) set_or_return(:path, arg, { kind_of: String })end

Chef::Providerdef load_current_resourceenddef whyrun_supported? trueenddef action_enable ...end

Why?

•Subclassing.

•No really, subclassing!

•Allows detailed, responsive customization.

Verbosity

•A lot of boilerplate code.

•Missing some LWRP DSL goodies.

Poise

Poiseclass Resource::Something < Resource include Poise ...endclass Provider::Something < Provider include Poise ...end

LWRP-ese

class Resource::Something < Resource include Poise actions(:enable, :disable) attribute(:path, kind_of: String)end

Notifying Block

def action_enable notifying_block do ... endend

Include Recipe

def action_enable include_recipe 'something'end

Lazy Defaults

class Resource::Something < Resource include Poise attribute(:path, default: lazy { node['path'] } )end

Option Collector

class Resource::Something < Resource include Poise attribute(:database, option_collector: True)end

Option Collector

something 'one' do database host: 'a', port: 8000end

Option Collector

something 'one' do database do host 'a' port 8000 endend

Sub-resources

class Resource::Something < Resource include Poise(container: true)end

Sub-resources

class Resource::Foo < Resource include Poise(parent: Something)end

Sub-resources

something 'one' do ... foo 'asdf' do ... endend

Sub-resources

something 'one' do ...end

foo 'asdf' do parent 'one'end

Sub-resources

something 'one'

foo 'asdf'

Distribution

• Cookbooks?

• Gems?