SlideShare a Scribd company logo
1 of 40
What Makes a Good
Cookbook?
Julian C. Dunn
Senior Consultant
Chef Software, Inc.
<jdunn@getchef.com>
Finding a Good Cookbook
Do judge a cookbook by its cover
Too Clever for Its Own Good
missing_attrs = %w{
postgres
}.select do |attr|
node['postgresql']['password'][attr].nil?
end.map { |attr| "node['postgresql']['password']['#{attr}']" }
if !missing_attrs.empty?
Chef::Application.fatal!([
"You must set #{missing_attrs.join(', ')} in chef-solo mode.",
"For more information, see
https://github.com/opscode-cookbooks/postgresql#chef-solo-note"
].join(' '))
end
Poking at Chef Internals
Chef::Application.fatal!([
"You must set #{missing_attrs.join(', ')} in chef-solo mode.",
"For more information, see
https://github.com/opscode-cookbooks/postgresql#chef-solo-note"
].join(' '))

• Other abuses: Messing with run_context and
run_state
Compile vs. Execute Errors
template "/etc/whatever.conf" do
...
not_if { foo }
end

not the same thing as
if foo
template "/etc/whatever.conf" do
...
end
end
Not declarative
execute “yum install httpd” do
not_if “rpm -qa | grep -x httpd”
end

• Also, the Chef recipe with 100 bash resource
declarations
Missing guards
execute "I will run every time" do
action :run
# because I don't have a guard here
end
Fear of LWRPs
• Missed abstraction opportunities
• No good example to put here; they’re all 200 lines
long (thus proving my point)
Hardcoded Strings
remote_file 'whatever.tar.gz' do
source 'http://hardcoded.url.com/’
end
Excess Conditions & Recipe Length

• https://github.com/opscode-cookbooks/mysql/blob/v3.0.1
• (We’ve since refactored this)
Good Cookbooks...
Put control flow in attributes
• Especially for cross-platform cookbooks
• Set common set of attributes, write common
behavior in recipe context
Control Flow in Attributes
case node['platform']
when "debian", "ubuntu"
default['postgresql']['client']['packages'] = %w{postgresql-client libpq-dev}
default['postgresql']['server']['packages'] = %w{postgresql}
default['postgresql']['contrib']['packages'] = %w{postgresql-contrib}
when "fedora", "amazon"
default['postgresql']['client']['packages'] = %w{postgresql-devel}
default['postgresql']['server']['packages'] = %w{postgresql-server}
default['postgresql']['contrib']['packages'] = %w{postgresql-contrib}
default['postgresql']['server']['service_name'] = "postgresql"
when "redhat", "centos", "scientific", "oracle"
default['postgresql']['version'] = "8.4"
default['postgresql']['dir'] = "/var/lib/pgsql/data"
if node['platform_version'].to_f >= 6.0
default['postgresql']['client']['packages'] = %w{postgresql-devel}
default['postgresql']['server']['packages'] = %w{postgresql-server}
default['postgresql']['contrib']['packages'] = %w{postgresql-contrib}
else
default['postgresql']['client']['packages'] = ["postgresql#{node['postgresql']['version'].split('.').join}-devel"]
default['postgresql']['server']['packages'] = ["postgresql#{node['postgresql']['version'].split('.').join}-server"]
default['postgresql']['contrib']['packages'] = ["postgresql#{node['postgresql']['version'].split('.').join}-contrib"]
end
default['postgresql']['server']['service_name'] = "postgresql"
Common Recipe Code
node['postgresql']['server']['packages'].each do |pg_pack|
package pg_pack
end

• Easy to support more platforms without modifying
recipe
Separate recipes by OS
• If things you do are very different per platform,
separate them into different recipes
default.rb
default.rb

server.rb
server.rb

_windows.rb
_windows.rb

_fedora.rb
_fedora.rb

_suse.rb
_suse.rb
“Public” versus “Private” recipes
• ‘_’ faux-namespacing
Do not abuse compile-time
loaded_recipes = if run_context.respond_to?(:loaded_recipes)
run_context.loaded_recipes
else
node.run_state[:seen_recipes]
end
node['mysql']['client']['packages'].each do |name|
resources("package[#{name}]").run_action(:install)
end

•.run_action(:must_die)
• Use sparingly, if at all!
Avoid poking Chef Internals
if some_error_condition
fail "Helpful error message"
# rather than Chef::Application.fatal!("error")
end

• Chef::Application.fatal is for use by Chef
itself
• fail or raise is better
Attributes only where necessary
• “Let’s create a node attribute for each of the 15,000
tunables in this daemon”
• Not necessary if you never touch 14,975 of those
knobs
Give people options for installation
git clone
git://github.com/foozolix/foozolix.git./configuremak
emake install

• Sigh.
• At least give people a way to install from packages.
• “Compile from source” should be banned in most cases.
Be declarative
• Know and use built-in Chef resources
• Know where to find LWRPs to avoid
batch/execute/powershell_script
• Consider using log resource versus Chef::Log
• Shows up in reporting as an updated resource instead of having to trawl
through client.log
• Set an idempotency guard!
• Log at the right log level
Repetition == LWRP Candidate
node['jboss']['instances'].each do |instance|
link "/etc/init.d/#{instance['name']}" do
to "/etc/init.d/jbossas"
end
template "/etc/sysconfig/#{instance['name']}" do
source "jbossas.sysconfig.erb"
owner node['jboss']['server']['user']
group node['jboss']['server']['group']
mode "00644"
variables(
:jbossconf => instance['name']
)
action :create
end
template "#{node['jboss']['server']['home']}/bin/standalone.sh" do
source "standalone.sh.erb"
owner node['jboss']['server']['user']
group node['jboss']['server']['group']
mode "00755"
action :create
end
link "#{node['jboss']['server']['home']}/bin/#{instance['name']}.sh" do
to "#{node['jboss']['server']['home']}/bin/standalone.sh"
end
end
Repetition == LWRP Candidate
• Perfect for abstracting!
• Resource interface:
actions :create, :delete
attribute :instance_name, :kind_of => String, :name_attribute => true
attribute :console_log_level, :kind_of => String, :required => true
attribute :datasources, :kind_of => Hash, :default => {}
.
.
.
default_action :create
Repetition == LWRP Candidate
jboss_instance "petstore" do
instance_name "can_haz_cheezburgerz"
console_log_level "DEBUG"
datasources {'db1' => 'jdbc://whatever:5432/db1'}
end

• Write/debug hard logic once
• Clear consumer interface
• Parameter validation & sanity checking
• Non-JBoss experts can invoke without knowing gnarly details
Write helper libraries
module MyCookbook
module Helper
# returns Windows friendly version of the provided path,
# ensures backslashes are used everywhere
def win_friendly_path(path)
path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR) if path
end
end
end

• Create reusable helper functions in pure Ruby
• Move repetitive detail out of recipe context.
Keep Recipes Small
• < 100 lines
• If longer than this, consider breaking up functionality
• Example: nagios server recipe does too much
• Installs Nagios
• Configures Nagios
• Pokes around in data bags for config items
Use Community Helpers
• Chef Sugar - http://code.sethvargo.com/chef-sugar/
• Chef Cutlery https://github.com/realityforge/chef-cutlery
• You can also crib ideas if you want to avoid external
dependencies
Wrap-Up
Testing
• I didn’t mention testing once in this talk!
• I’m assuming you will write tests for your cookbooks.
• A whole other talk...
• ... including good/bad things to test
Make your code aromatic
• Keep recipes small
• Keep recipes simple
• Use a consistent style
• Use Foodcritic
Beware Expertise Bias
• Hide gnarly details from recipe context
• Libraries
• LWRPs
• Attributes
• Resist urge to be overly clever - not everyone’s an expert
• Akin to the one-line sed/awk script
• http://tinyurl.com/the-expertise-bias
Learn from Software Developers
• Everything I told you about information hiding, design
patterns, testing, etc.
• Ops can learn from devs as well!
• Maybe we should call it OpsDev...
Thank You!
E: jdunn@getchef.com
G: https://github.com/juliandunn
T: @julian_dunn
W: www.juliandunn.net
What Makes a Good Cookbook?

More Related Content

What's hot

Chef Fundamentals Training Series Module 4: The Chef Client Run and Expanding...
Chef Fundamentals Training Series Module 4: The Chef Client Run and Expanding...Chef Fundamentals Training Series Module 4: The Chef Client Run and Expanding...
Chef Fundamentals Training Series Module 4: The Chef Client Run and Expanding...Chef Software, Inc.
 
Introduction to Chef
Introduction to ChefIntroduction to Chef
Introduction to ChefKnoldus Inc.
 
Infrastructure Automation with Chef & Ansible
Infrastructure Automation with Chef & AnsibleInfrastructure Automation with Chef & Ansible
Infrastructure Automation with Chef & Ansiblewajrcs
 
Using Test Kitchen for testing Chef cookbooks
Using Test Kitchen for testing Chef cookbooksUsing Test Kitchen for testing Chef cookbooks
Using Test Kitchen for testing Chef cookbooksTimur Batyrshin
 
Opscode Webinar: Managing Your VMware Infrastructure with Chef
Opscode Webinar: Managing Your VMware Infrastructure with ChefOpscode Webinar: Managing Your VMware Infrastructure with Chef
Opscode Webinar: Managing Your VMware Infrastructure with ChefChef Software, Inc.
 
Ansible 2 and Ansible Galaxy 2
Ansible 2 and Ansible Galaxy 2Ansible 2 and Ansible Galaxy 2
Ansible 2 and Ansible Galaxy 2Jeff Geerling
 
Orchestration? You Don't Need Orchestration. What You Want is Choreography.
Orchestration? You Don't Need Orchestration. What You Want is Choreography.Orchestration? You Don't Need Orchestration. What You Want is Choreography.
Orchestration? You Don't Need Orchestration. What You Want is Choreography.Julian Dunn
 
Infrastructure Automation with Chef
Infrastructure Automation with ChefInfrastructure Automation with Chef
Infrastructure Automation with ChefJonathan Weiss
 
Server Installation and Configuration with Chef
Server Installation and Configuration with ChefServer Installation and Configuration with Chef
Server Installation and Configuration with ChefRaimonds Simanovskis
 
Opscode Webinar: Cooking with Chef on Microsoft Windows
Opscode Webinar: Cooking with Chef on Microsoft WindowsOpscode Webinar: Cooking with Chef on Microsoft Windows
Opscode Webinar: Cooking with Chef on Microsoft WindowsChef Software, Inc.
 
Chef Fundamentals Training Series Module 3: Setting up Nodes and Cookbook Aut...
Chef Fundamentals Training Series Module 3: Setting up Nodes and Cookbook Aut...Chef Fundamentals Training Series Module 3: Setting up Nodes and Cookbook Aut...
Chef Fundamentals Training Series Module 3: Setting up Nodes and Cookbook Aut...Chef Software, Inc.
 
Chef-Zero & Local Mode
Chef-Zero & Local ModeChef-Zero & Local Mode
Chef-Zero & Local ModeMichael Goetz
 
Superb Supervision of Short-lived Servers with Sensu
Superb Supervision of Short-lived Servers with SensuSuperb Supervision of Short-lived Servers with Sensu
Superb Supervision of Short-lived Servers with SensuPaul O'Connor
 

What's hot (20)

The unintended benefits of Chef
The unintended benefits of ChefThe unintended benefits of Chef
The unintended benefits of Chef
 
Chef Fundamentals Training Series Module 4: The Chef Client Run and Expanding...
Chef Fundamentals Training Series Module 4: The Chef Client Run and Expanding...Chef Fundamentals Training Series Module 4: The Chef Client Run and Expanding...
Chef Fundamentals Training Series Module 4: The Chef Client Run and Expanding...
 
Introduction to Chef
Introduction to ChefIntroduction to Chef
Introduction to Chef
 
Chef
ChefChef
Chef
 
Infrastructure Automation with Chef & Ansible
Infrastructure Automation with Chef & AnsibleInfrastructure Automation with Chef & Ansible
Infrastructure Automation with Chef & Ansible
 
Using Test Kitchen for testing Chef cookbooks
Using Test Kitchen for testing Chef cookbooksUsing Test Kitchen for testing Chef cookbooks
Using Test Kitchen for testing Chef cookbooks
 
Opscode Webinar: Managing Your VMware Infrastructure with Chef
Opscode Webinar: Managing Your VMware Infrastructure with ChefOpscode Webinar: Managing Your VMware Infrastructure with Chef
Opscode Webinar: Managing Your VMware Infrastructure with Chef
 
Chef training - Day3
Chef training - Day3Chef training - Day3
Chef training - Day3
 
Ansible 2 and Ansible Galaxy 2
Ansible 2 and Ansible Galaxy 2Ansible 2 and Ansible Galaxy 2
Ansible 2 and Ansible Galaxy 2
 
Chef introduction
Chef introductionChef introduction
Chef introduction
 
Chef training Day5
Chef training Day5Chef training Day5
Chef training Day5
 
Chef training Day4
Chef training Day4Chef training Day4
Chef training Day4
 
Configuration management with Chef
Configuration management with ChefConfiguration management with Chef
Configuration management with Chef
 
Orchestration? You Don't Need Orchestration. What You Want is Choreography.
Orchestration? You Don't Need Orchestration. What You Want is Choreography.Orchestration? You Don't Need Orchestration. What You Want is Choreography.
Orchestration? You Don't Need Orchestration. What You Want is Choreography.
 
Infrastructure Automation with Chef
Infrastructure Automation with ChefInfrastructure Automation with Chef
Infrastructure Automation with Chef
 
Server Installation and Configuration with Chef
Server Installation and Configuration with ChefServer Installation and Configuration with Chef
Server Installation and Configuration with Chef
 
Opscode Webinar: Cooking with Chef on Microsoft Windows
Opscode Webinar: Cooking with Chef on Microsoft WindowsOpscode Webinar: Cooking with Chef on Microsoft Windows
Opscode Webinar: Cooking with Chef on Microsoft Windows
 
Chef Fundamentals Training Series Module 3: Setting up Nodes and Cookbook Aut...
Chef Fundamentals Training Series Module 3: Setting up Nodes and Cookbook Aut...Chef Fundamentals Training Series Module 3: Setting up Nodes and Cookbook Aut...
Chef Fundamentals Training Series Module 3: Setting up Nodes and Cookbook Aut...
 
Chef-Zero & Local Mode
Chef-Zero & Local ModeChef-Zero & Local Mode
Chef-Zero & Local Mode
 
Superb Supervision of Short-lived Servers with Sensu
Superb Supervision of Short-lived Servers with SensuSuperb Supervision of Short-lived Servers with Sensu
Superb Supervision of Short-lived Servers with Sensu
 

Viewers also liked

Chef NYC Users' Group - Announcements for June 2014
Chef NYC Users' Group - Announcements for June 2014Chef NYC Users' Group - Announcements for June 2014
Chef NYC Users' Group - Announcements for June 2014Julian Dunn
 
Chef-NYC Announcements July 2014
Chef-NYC Announcements July 2014Chef-NYC Announcements July 2014
Chef-NYC Announcements July 2014Julian Dunn
 
Automating That "Other" OS
Automating That "Other" OSAutomating That "Other" OS
Automating That "Other" OSJulian Dunn
 
Configuration Management in a Containerized World
Configuration Management in a Containerized WorldConfiguration Management in a Containerized World
Configuration Management in a Containerized WorldJulian Dunn
 
Chef Cookbook Governance BoF at ChefConf
Chef Cookbook Governance BoF at ChefConfChef Cookbook Governance BoF at ChefConf
Chef Cookbook Governance BoF at ChefConfJulian Dunn
 
Configuration Management Isn't Everything
Configuration Management Isn't EverythingConfiguration Management Isn't Everything
Configuration Management Isn't EverythingJulian Dunn
 
Cooking with Chef on Windows: 2015 Edition
Cooking with Chef on Windows: 2015 EditionCooking with Chef on Windows: 2015 Edition
Cooking with Chef on Windows: 2015 EditionJulian Dunn
 
An Introduction to Shef, the Chef Shell
An Introduction to Shef, the Chef ShellAn Introduction to Shef, the Chef Shell
An Introduction to Shef, the Chef ShellJulian Dunn
 
Cooking with Chef on Windows
Cooking with Chef on WindowsCooking with Chef on Windows
Cooking with Chef on WindowsJulian Dunn
 
Improving Your Mac Productivity
Improving Your Mac ProductivityImproving Your Mac Productivity
Improving Your Mac ProductivityJulian Dunn
 
Chef and PowerShell Desired State Configuration
Chef and PowerShell Desired State ConfigurationChef and PowerShell Desired State Configuration
Chef and PowerShell Desired State ConfigurationJulian Dunn
 
Chef Workflow Strategies at SecondMarket
Chef Workflow Strategies at SecondMarketChef Workflow Strategies at SecondMarket
Chef Workflow Strategies at SecondMarketJulian Dunn
 
ChefConf 2013: Beginner Chef Antipatterns
ChefConf 2013: Beginner Chef AntipatternsChefConf 2013: Beginner Chef Antipatterns
ChefConf 2013: Beginner Chef AntipatternsJulian Dunn
 
An Introduction to DevOps with Chef
An Introduction to DevOps with ChefAn Introduction to DevOps with Chef
An Introduction to DevOps with ChefJulian Dunn
 
Chef Cookbook Testing and Continuous Integration
Chef Cookbook Testing and Continuous IntegrationChef Cookbook Testing and Continuous Integration
Chef Cookbook Testing and Continuous IntegrationJulian Dunn
 

Viewers also liked (16)

Chef NYC Users' Group - Announcements for June 2014
Chef NYC Users' Group - Announcements for June 2014Chef NYC Users' Group - Announcements for June 2014
Chef NYC Users' Group - Announcements for June 2014
 
Chef-NYC Announcements July 2014
Chef-NYC Announcements July 2014Chef-NYC Announcements July 2014
Chef-NYC Announcements July 2014
 
Automating That "Other" OS
Automating That "Other" OSAutomating That "Other" OS
Automating That "Other" OS
 
Configuration Management in a Containerized World
Configuration Management in a Containerized WorldConfiguration Management in a Containerized World
Configuration Management in a Containerized World
 
Chef Cookbook Governance BoF at ChefConf
Chef Cookbook Governance BoF at ChefConfChef Cookbook Governance BoF at ChefConf
Chef Cookbook Governance BoF at ChefConf
 
Configuration Management Isn't Everything
Configuration Management Isn't EverythingConfiguration Management Isn't Everything
Configuration Management Isn't Everything
 
Cooking with Chef on Windows: 2015 Edition
Cooking with Chef on Windows: 2015 EditionCooking with Chef on Windows: 2015 Edition
Cooking with Chef on Windows: 2015 Edition
 
An Introduction to Shef, the Chef Shell
An Introduction to Shef, the Chef ShellAn Introduction to Shef, the Chef Shell
An Introduction to Shef, the Chef Shell
 
Cooking with Chef on Windows
Cooking with Chef on WindowsCooking with Chef on Windows
Cooking with Chef on Windows
 
Chef on AIX
Chef on AIXChef on AIX
Chef on AIX
 
Improving Your Mac Productivity
Improving Your Mac ProductivityImproving Your Mac Productivity
Improving Your Mac Productivity
 
Chef and PowerShell Desired State Configuration
Chef and PowerShell Desired State ConfigurationChef and PowerShell Desired State Configuration
Chef and PowerShell Desired State Configuration
 
Chef Workflow Strategies at SecondMarket
Chef Workflow Strategies at SecondMarketChef Workflow Strategies at SecondMarket
Chef Workflow Strategies at SecondMarket
 
ChefConf 2013: Beginner Chef Antipatterns
ChefConf 2013: Beginner Chef AntipatternsChefConf 2013: Beginner Chef Antipatterns
ChefConf 2013: Beginner Chef Antipatterns
 
An Introduction to DevOps with Chef
An Introduction to DevOps with ChefAn Introduction to DevOps with Chef
An Introduction to DevOps with Chef
 
Chef Cookbook Testing and Continuous Integration
Chef Cookbook Testing and Continuous IntegrationChef Cookbook Testing and Continuous Integration
Chef Cookbook Testing and Continuous Integration
 

Similar to What Makes a Good Cookbook?

AWS OpsWorks Under the Hood (DMG304) | AWS re:Invent 2013
AWS OpsWorks Under the Hood (DMG304) | AWS re:Invent 2013AWS OpsWorks Under the Hood (DMG304) | AWS re:Invent 2013
AWS OpsWorks Under the Hood (DMG304) | AWS re:Invent 2013Amazon Web Services
 
Cookbook refactoring & abstracting logic to Ruby(gems)
Cookbook refactoring & abstracting logic to Ruby(gems)Cookbook refactoring & abstracting logic to Ruby(gems)
Cookbook refactoring & abstracting logic to Ruby(gems)Chef Software, Inc.
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppSmartLogic
 
Test-Driven Infrastructure with Chef
Test-Driven Infrastructure with ChefTest-Driven Infrastructure with Chef
Test-Driven Infrastructure with ChefMichael Lihs
 
Cook Infrastructure with chef -- Justeat.IN
Cook Infrastructure with chef  -- Justeat.INCook Infrastructure with chef  -- Justeat.IN
Cook Infrastructure with chef -- Justeat.INRajesh Hegde
 
Common configuration with Data Bags - Fundamentals Webinar Series Part 4
Common configuration with Data Bags - Fundamentals Webinar Series Part 4Common configuration with Data Bags - Fundamentals Webinar Series Part 4
Common configuration with Data Bags - Fundamentals Webinar Series Part 4Chef
 
Introduction to Chef
Introduction to ChefIntroduction to Chef
Introduction to Chefkevsmith
 
Chef or how to make computers do the work for us
Chef or how to make computers do the work for usChef or how to make computers do the work for us
Chef or how to make computers do the work for ussickill
 
Kickstarter - Chef Opswork
Kickstarter - Chef OpsworkKickstarter - Chef Opswork
Kickstarter - Chef OpsworkHamza Waqas
 
Cooking Perl with Chef: Real World Tutorial with Jitterbug
Cooking Perl with Chef: Real World Tutorial with JitterbugCooking Perl with Chef: Real World Tutorial with Jitterbug
Cooking Perl with Chef: Real World Tutorial with JitterbugDavid Golden
 
EC2 AMI Factory with Chef, Berkshelf, and Packer
EC2 AMI Factory with Chef, Berkshelf, and PackerEC2 AMI Factory with Chef, Berkshelf, and Packer
EC2 AMI Factory with Chef, Berkshelf, and PackerGeorge Miranda
 
Community Cookbooks & further resources - Fundamentals Webinar Series Part 6
Community Cookbooks & further resources - Fundamentals Webinar Series Part 6Community Cookbooks & further resources - Fundamentals Webinar Series Part 6
Community Cookbooks & further resources - Fundamentals Webinar Series Part 6Chef
 
Chef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureChef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureMichaël Lopez
 
Node object and roles - Fundamentals Webinar Series Part 3
Node object and roles - Fundamentals Webinar Series Part 3Node object and roles - Fundamentals Webinar Series Part 3
Node object and roles - Fundamentals Webinar Series Part 3Chef
 
Introduction To Continuous Compliance & Remediation
Introduction To Continuous Compliance & RemediationIntroduction To Continuous Compliance & Remediation
Introduction To Continuous Compliance & RemediationNicole Johnson
 
Chef - Administration for programmers
Chef - Administration for programmersChef - Administration for programmers
Chef - Administration for programmersmrsabo
 
DevOps Hackathon: Session 3 - Test Driven Infrastructure
DevOps Hackathon: Session 3 - Test Driven InfrastructureDevOps Hackathon: Session 3 - Test Driven Infrastructure
DevOps Hackathon: Session 3 - Test Driven InfrastructureAntons Kranga
 
BP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesAlfresco Software
 
Chef basics - write infrastructure as code
Chef basics - write infrastructure as codeChef basics - write infrastructure as code
Chef basics - write infrastructure as codestevaaa
 

Similar to What Makes a Good Cookbook? (20)

AWS OpsWorks Under the Hood (DMG304) | AWS re:Invent 2013
AWS OpsWorks Under the Hood (DMG304) | AWS re:Invent 2013AWS OpsWorks Under the Hood (DMG304) | AWS re:Invent 2013
AWS OpsWorks Under the Hood (DMG304) | AWS re:Invent 2013
 
Cookbook refactoring & abstracting logic to Ruby(gems)
Cookbook refactoring & abstracting logic to Ruby(gems)Cookbook refactoring & abstracting logic to Ruby(gems)
Cookbook refactoring & abstracting logic to Ruby(gems)
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
 
Test-Driven Infrastructure with Chef
Test-Driven Infrastructure with ChefTest-Driven Infrastructure with Chef
Test-Driven Infrastructure with Chef
 
Cook Infrastructure with chef -- Justeat.IN
Cook Infrastructure with chef  -- Justeat.INCook Infrastructure with chef  -- Justeat.IN
Cook Infrastructure with chef -- Justeat.IN
 
Common configuration with Data Bags - Fundamentals Webinar Series Part 4
Common configuration with Data Bags - Fundamentals Webinar Series Part 4Common configuration with Data Bags - Fundamentals Webinar Series Part 4
Common configuration with Data Bags - Fundamentals Webinar Series Part 4
 
Introduction to Chef
Introduction to ChefIntroduction to Chef
Introduction to Chef
 
Chef solo the beginning
Chef solo the beginning Chef solo the beginning
Chef solo the beginning
 
Chef or how to make computers do the work for us
Chef or how to make computers do the work for usChef or how to make computers do the work for us
Chef or how to make computers do the work for us
 
Kickstarter - Chef Opswork
Kickstarter - Chef OpsworkKickstarter - Chef Opswork
Kickstarter - Chef Opswork
 
Cooking Perl with Chef: Real World Tutorial with Jitterbug
Cooking Perl with Chef: Real World Tutorial with JitterbugCooking Perl with Chef: Real World Tutorial with Jitterbug
Cooking Perl with Chef: Real World Tutorial with Jitterbug
 
EC2 AMI Factory with Chef, Berkshelf, and Packer
EC2 AMI Factory with Chef, Berkshelf, and PackerEC2 AMI Factory with Chef, Berkshelf, and Packer
EC2 AMI Factory with Chef, Berkshelf, and Packer
 
Community Cookbooks & further resources - Fundamentals Webinar Series Part 6
Community Cookbooks & further resources - Fundamentals Webinar Series Part 6Community Cookbooks & further resources - Fundamentals Webinar Series Part 6
Community Cookbooks & further resources - Fundamentals Webinar Series Part 6
 
Chef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureChef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructure
 
Node object and roles - Fundamentals Webinar Series Part 3
Node object and roles - Fundamentals Webinar Series Part 3Node object and roles - Fundamentals Webinar Series Part 3
Node object and roles - Fundamentals Webinar Series Part 3
 
Introduction To Continuous Compliance & Remediation
Introduction To Continuous Compliance & RemediationIntroduction To Continuous Compliance & Remediation
Introduction To Continuous Compliance & Remediation
 
Chef - Administration for programmers
Chef - Administration for programmersChef - Administration for programmers
Chef - Administration for programmers
 
DevOps Hackathon: Session 3 - Test Driven Infrastructure
DevOps Hackathon: Session 3 - Test Driven InfrastructureDevOps Hackathon: Session 3 - Test Driven Infrastructure
DevOps Hackathon: Session 3 - Test Driven Infrastructure
 
BP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best Practices
 
Chef basics - write infrastructure as code
Chef basics - write infrastructure as codeChef basics - write infrastructure as code
Chef basics - write infrastructure as code
 

Recently uploaded

THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONTHEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONHumphrey A Beña
 
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...JojoEDelaCruz
 
Transaction Management in Database Management System
Transaction Management in Database Management SystemTransaction Management in Database Management System
Transaction Management in Database Management SystemChristalin Nelson
 
Oppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmOppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmStan Meyer
 
ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4MiaBumagat1
 
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)lakshayb543
 
TEACHER REFLECTION FORM (NEW SET........).docx
TEACHER REFLECTION FORM (NEW SET........).docxTEACHER REFLECTION FORM (NEW SET........).docx
TEACHER REFLECTION FORM (NEW SET........).docxruthvilladarez
 
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfInclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfTechSoup
 
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdfGrade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdfJemuel Francisco
 
EMBODO Lesson Plan Grade 9 Law of Sines.docx
EMBODO Lesson Plan Grade 9 Law of Sines.docxEMBODO Lesson Plan Grade 9 Law of Sines.docx
EMBODO Lesson Plan Grade 9 Law of Sines.docxElton John Embodo
 
ROLES IN A STAGE PRODUCTION in arts.pptx
ROLES IN A STAGE PRODUCTION in arts.pptxROLES IN A STAGE PRODUCTION in arts.pptx
ROLES IN A STAGE PRODUCTION in arts.pptxVanesaIglesias10
 
Dust Of Snow By Robert Frost Class-X English CBSE
Dust Of Snow By Robert Frost Class-X English CBSEDust Of Snow By Robert Frost Class-X English CBSE
Dust Of Snow By Robert Frost Class-X English CBSEaurabinda banchhor
 
Keynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designKeynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designMIPLM
 
Expanded definition: technical and operational
Expanded definition: technical and operationalExpanded definition: technical and operational
Expanded definition: technical and operationalssuser3e220a
 
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxINTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxHumphrey A Beña
 
The Contemporary World: The Globalization of World Politics
The Contemporary World: The Globalization of World PoliticsThe Contemporary World: The Globalization of World Politics
The Contemporary World: The Globalization of World PoliticsRommel Regala
 
Choosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for ParentsChoosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for Parentsnavabharathschool99
 
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxMULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxAnupkumar Sharma
 

Recently uploaded (20)

THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONTHEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
 
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
 
Transaction Management in Database Management System
Transaction Management in Database Management SystemTransaction Management in Database Management System
Transaction Management in Database Management System
 
YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptxYOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
YOUVE_GOT_EMAIL_PRELIMS_EL_DORADO_2024.pptx
 
Oppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmOppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and Film
 
ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4ANG SEKTOR NG agrikultura.pptx QUARTER 4
ANG SEKTOR NG agrikultura.pptx QUARTER 4
 
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
 
TEACHER REFLECTION FORM (NEW SET........).docx
TEACHER REFLECTION FORM (NEW SET........).docxTEACHER REFLECTION FORM (NEW SET........).docx
TEACHER REFLECTION FORM (NEW SET........).docx
 
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfInclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
 
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdfGrade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
Grade 9 Quarter 4 Dll Grade 9 Quarter 4 DLL.pdf
 
FINALS_OF_LEFT_ON_C'N_EL_DORADO_2024.pptx
FINALS_OF_LEFT_ON_C'N_EL_DORADO_2024.pptxFINALS_OF_LEFT_ON_C'N_EL_DORADO_2024.pptx
FINALS_OF_LEFT_ON_C'N_EL_DORADO_2024.pptx
 
EMBODO Lesson Plan Grade 9 Law of Sines.docx
EMBODO Lesson Plan Grade 9 Law of Sines.docxEMBODO Lesson Plan Grade 9 Law of Sines.docx
EMBODO Lesson Plan Grade 9 Law of Sines.docx
 
ROLES IN A STAGE PRODUCTION in arts.pptx
ROLES IN A STAGE PRODUCTION in arts.pptxROLES IN A STAGE PRODUCTION in arts.pptx
ROLES IN A STAGE PRODUCTION in arts.pptx
 
Dust Of Snow By Robert Frost Class-X English CBSE
Dust Of Snow By Robert Frost Class-X English CBSEDust Of Snow By Robert Frost Class-X English CBSE
Dust Of Snow By Robert Frost Class-X English CBSE
 
Keynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designKeynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-design
 
Expanded definition: technical and operational
Expanded definition: technical and operationalExpanded definition: technical and operational
Expanded definition: technical and operational
 
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptxINTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
INTRODUCTION TO CATHOLIC CHRISTOLOGY.pptx
 
The Contemporary World: The Globalization of World Politics
The Contemporary World: The Globalization of World PoliticsThe Contemporary World: The Globalization of World Politics
The Contemporary World: The Globalization of World Politics
 
Choosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for ParentsChoosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for Parents
 
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptxMULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
MULTIDISCIPLINRY NATURE OF THE ENVIRONMENTAL STUDIES.pptx
 

What Makes a Good Cookbook?

  • 1. What Makes a Good Cookbook? Julian C. Dunn Senior Consultant Chef Software, Inc. <jdunn@getchef.com>
  • 2. Finding a Good Cookbook
  • 3.
  • 4. Do judge a cookbook by its cover
  • 5.
  • 6.
  • 7.
  • 8.
  • 9. Too Clever for Its Own Good missing_attrs = %w{ postgres }.select do |attr| node['postgresql']['password'][attr].nil? end.map { |attr| "node['postgresql']['password']['#{attr}']" } if !missing_attrs.empty? Chef::Application.fatal!([ "You must set #{missing_attrs.join(', ')} in chef-solo mode.", "For more information, see https://github.com/opscode-cookbooks/postgresql#chef-solo-note" ].join(' ')) end
  • 10. Poking at Chef Internals Chef::Application.fatal!([ "You must set #{missing_attrs.join(', ')} in chef-solo mode.", "For more information, see https://github.com/opscode-cookbooks/postgresql#chef-solo-note" ].join(' ')) • Other abuses: Messing with run_context and run_state
  • 11. Compile vs. Execute Errors template "/etc/whatever.conf" do ... not_if { foo } end not the same thing as if foo template "/etc/whatever.conf" do ... end end
  • 12. Not declarative execute “yum install httpd” do not_if “rpm -qa | grep -x httpd” end • Also, the Chef recipe with 100 bash resource declarations
  • 13. Missing guards execute "I will run every time" do action :run # because I don't have a guard here end
  • 14. Fear of LWRPs • Missed abstraction opportunities • No good example to put here; they’re all 200 lines long (thus proving my point)
  • 15. Hardcoded Strings remote_file 'whatever.tar.gz' do source 'http://hardcoded.url.com/’ end
  • 16. Excess Conditions & Recipe Length • https://github.com/opscode-cookbooks/mysql/blob/v3.0.1 • (We’ve since refactored this)
  • 18. Put control flow in attributes • Especially for cross-platform cookbooks • Set common set of attributes, write common behavior in recipe context
  • 19. Control Flow in Attributes case node['platform'] when "debian", "ubuntu" default['postgresql']['client']['packages'] = %w{postgresql-client libpq-dev} default['postgresql']['server']['packages'] = %w{postgresql} default['postgresql']['contrib']['packages'] = %w{postgresql-contrib} when "fedora", "amazon" default['postgresql']['client']['packages'] = %w{postgresql-devel} default['postgresql']['server']['packages'] = %w{postgresql-server} default['postgresql']['contrib']['packages'] = %w{postgresql-contrib} default['postgresql']['server']['service_name'] = "postgresql" when "redhat", "centos", "scientific", "oracle" default['postgresql']['version'] = "8.4" default['postgresql']['dir'] = "/var/lib/pgsql/data" if node['platform_version'].to_f >= 6.0 default['postgresql']['client']['packages'] = %w{postgresql-devel} default['postgresql']['server']['packages'] = %w{postgresql-server} default['postgresql']['contrib']['packages'] = %w{postgresql-contrib} else default['postgresql']['client']['packages'] = ["postgresql#{node['postgresql']['version'].split('.').join}-devel"] default['postgresql']['server']['packages'] = ["postgresql#{node['postgresql']['version'].split('.').join}-server"] default['postgresql']['contrib']['packages'] = ["postgresql#{node['postgresql']['version'].split('.').join}-contrib"] end default['postgresql']['server']['service_name'] = "postgresql"
  • 20. Common Recipe Code node['postgresql']['server']['packages'].each do |pg_pack| package pg_pack end • Easy to support more platforms without modifying recipe
  • 21. Separate recipes by OS • If things you do are very different per platform, separate them into different recipes default.rb default.rb server.rb server.rb _windows.rb _windows.rb _fedora.rb _fedora.rb _suse.rb _suse.rb
  • 22. “Public” versus “Private” recipes • ‘_’ faux-namespacing
  • 23. Do not abuse compile-time loaded_recipes = if run_context.respond_to?(:loaded_recipes) run_context.loaded_recipes else node.run_state[:seen_recipes] end node['mysql']['client']['packages'].each do |name| resources("package[#{name}]").run_action(:install) end •.run_action(:must_die) • Use sparingly, if at all!
  • 24. Avoid poking Chef Internals if some_error_condition fail "Helpful error message" # rather than Chef::Application.fatal!("error") end • Chef::Application.fatal is for use by Chef itself • fail or raise is better
  • 25. Attributes only where necessary • “Let’s create a node attribute for each of the 15,000 tunables in this daemon” • Not necessary if you never touch 14,975 of those knobs
  • 26. Give people options for installation git clone git://github.com/foozolix/foozolix.git./configuremak emake install • Sigh. • At least give people a way to install from packages. • “Compile from source” should be banned in most cases.
  • 27. Be declarative • Know and use built-in Chef resources • Know where to find LWRPs to avoid batch/execute/powershell_script • Consider using log resource versus Chef::Log • Shows up in reporting as an updated resource instead of having to trawl through client.log • Set an idempotency guard! • Log at the right log level
  • 28. Repetition == LWRP Candidate node['jboss']['instances'].each do |instance| link "/etc/init.d/#{instance['name']}" do to "/etc/init.d/jbossas" end template "/etc/sysconfig/#{instance['name']}" do source "jbossas.sysconfig.erb" owner node['jboss']['server']['user'] group node['jboss']['server']['group'] mode "00644" variables( :jbossconf => instance['name'] ) action :create end template "#{node['jboss']['server']['home']}/bin/standalone.sh" do source "standalone.sh.erb" owner node['jboss']['server']['user'] group node['jboss']['server']['group'] mode "00755" action :create end link "#{node['jboss']['server']['home']}/bin/#{instance['name']}.sh" do to "#{node['jboss']['server']['home']}/bin/standalone.sh" end end
  • 29. Repetition == LWRP Candidate • Perfect for abstracting! • Resource interface: actions :create, :delete attribute :instance_name, :kind_of => String, :name_attribute => true attribute :console_log_level, :kind_of => String, :required => true attribute :datasources, :kind_of => Hash, :default => {} . . . default_action :create
  • 30. Repetition == LWRP Candidate jboss_instance "petstore" do instance_name "can_haz_cheezburgerz" console_log_level "DEBUG" datasources {'db1' => 'jdbc://whatever:5432/db1'} end • Write/debug hard logic once • Clear consumer interface • Parameter validation & sanity checking • Non-JBoss experts can invoke without knowing gnarly details
  • 31. Write helper libraries module MyCookbook module Helper # returns Windows friendly version of the provided path, # ensures backslashes are used everywhere def win_friendly_path(path) path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR) if path end end end • Create reusable helper functions in pure Ruby • Move repetitive detail out of recipe context.
  • 32. Keep Recipes Small • < 100 lines • If longer than this, consider breaking up functionality • Example: nagios server recipe does too much • Installs Nagios • Configures Nagios • Pokes around in data bags for config items
  • 33. Use Community Helpers • Chef Sugar - http://code.sethvargo.com/chef-sugar/ • Chef Cutlery https://github.com/realityforge/chef-cutlery • You can also crib ideas if you want to avoid external dependencies
  • 35. Testing • I didn’t mention testing once in this talk! • I’m assuming you will write tests for your cookbooks. • A whole other talk... • ... including good/bad things to test
  • 36. Make your code aromatic • Keep recipes small • Keep recipes simple • Use a consistent style • Use Foodcritic
  • 37. Beware Expertise Bias • Hide gnarly details from recipe context • Libraries • LWRPs • Attributes • Resist urge to be overly clever - not everyone’s an expert • Akin to the one-line sed/awk script • http://tinyurl.com/the-expertise-bias
  • 38. Learn from Software Developers • Everything I told you about information hiding, design patterns, testing, etc. • Ops can learn from devs as well! • Maybe we should call it OpsDev...
  • 39. Thank You! E: jdunn@getchef.com G: https://github.com/juliandunn T: @julian_dunn W: www.juliandunn.net

Editor's Notes

  1. Other things to add: - shell_out versus shell_out! (and also using shell_out rather than ‘system’ or backticks (ugh))
  2. If you’ve ever been to Chef training, we tell you... don’t invent your own cookbook if someone else has done it before. But when you Google, or search on GitHub/StackOverflow/Chef Community site and look for a cookbook, how do you know if it’s any good? More importantly, if you’re writing a cookbook that you hope to publish, or patches for Chef’s community cookbooks, how do you make a “good” cookbook?
  3. Updated recently?
  4. Lots of outstanding pull requests that haven’t been addressed in years?
  5. No docs? These things all tell you whether the code is maintained and how alive it is. If you work in open source, this should already be known to you -- how to detect how healthy an open source project is. So I won’t spend too much more time on that.
  6. What about what the code looks like inside? Code smell From 30,000 feet, how can you detect whether a cookbook smells good or bad?
  7. Not everyone is a Ruby genius. This is wrong on so many levels, not the least of which... over-abstraction (using a sledgehammer to kill a fly)
  8. Abuse of batch/execute/powershell_script when built-in Chef resources will do Another example: remote_file over execute+curl/wget
  9. Always ensure idempotence! (Some exceptions where it’s not possible, but doing so will allow you to establish a baseline # of resources updated, close to zero, that shows whether your systems are in compliance with policy.
  10. Being afraid of writing LWRPs, so not encapsulating repetitive logic in an LWRP with inline resources Example: Previous job’s Jetty cookbook, where it was a giant loop over a giant attribute array for each Jetty instance
  11. Particularly in URLs! Not everyone has Internet access! Make this stuff attributes so people can override it
  12. Too many conditionals, too much control flow, trying to do a “one size fits all” approach
  13. Becomes an arms race of what you can do earlier and earlier
  14. Nothing worse than a cookbook that purports to install “foozolix” and the recipe consists ofgit clone git://github.com/foozolix/foozolix.git./configuremakemake installEspecially if foozolix is available in a distro package!“compile from source” should be banned in most cases
  15. So much of IT is just pattern recognition... the “app” + “instance of app” is a common pattern. (JBoss instance, Endeca “app”, whatever) But don’t abuse LWRPs. If it’s not repeatable and a consumable interface by external parties (e.g. you’re only going to do it once), then don’t bother LWRP-ing. TODO: Show refactoring of a tomcat instance into an LWRP
  16. (A discourse here about how small a recipe should be -- basically it should encapsulate atomic functionality that someone will call, all or nothing) Nothing more irritating than a recipe that does 95% of what you want, and the 5% of it is some side effect that many people don’t want to do -- e.g. Nagios recipe, installing Nagios and all the data bag search stuff is stuffed into one recipe
  17. Caveat: Locks you into particular gems.
  18. ChefSpec 3.0 for unit testing. ServerSpec for integration testing. Test Kitchen to tie it all together.
  19.   - Make your code smell good both near and far.    - Keep recipes simple    - Keep recipes small (more recipes in a cookbook are ok)    - I don’t care what your style is, just use a consistent one — Rubocop is good for enforcing whatever style you decide on. Nothing worse than mixing and matching syntax (symbols versus strings versus dot-notation is the worst)    - Foodcritic is also good for enforcing cookbook correctness -- not just a linter
  20. http://www.psychologytoday.com/blog/everybody-is-stupid-except-you/201008/the-expertise-bias Imagine you are a DMV worker. It&apos;s your first day on the job. Someone asks you a question and you can see why they&apos;re confused. You&apos;re a bit confused yourself. You help them out. But now it&apos;s your 1,000th day at the DMV. You&apos;ve had 10,000 people ask you the same question. The answer, which used to seem a bit obscure, is SO OBVIOUS you want to throw up. You can&apos;t believe that these people don&apos;t know what they&apos;re supposed to do! You look at the customer and think: &quot;You filled out Form 332b even though you have an RV and you&apos;re left handed?! You&apos;re an idiot.&quot;