SlideShare a Scribd company logo
What Makes a Good
Cookbook?
Julian C. Dunn
Senior Consulting Engineer Engineering Team Lead
Chef Software, Inc.
<jdunn@getchef.com>
$ whoami
• Consulting Engineer
Engineering Team Lead at Chef
• System Administrator
• Reformed Java Developer
• Writes silly code like this
•https://github.com/juliandunn/
doge-chef-formatter
Finding a Good Cookbook
LMGTCFY
Do judge a cookbook by its cover
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
Too Clever for Its Own Good
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(' '))
Poking at Chef Internals
• Other abuses: Messing with run_context and
run_state
if node.run_list.recipes.include?('foo::bar')
...
end
Poking run_list and environment
if node.chef_environment == 'production'
...
end
• Use feature flags!
template "/etc/whatever.conf" do
...
not_if { foo }
end
Compile vs. Execute Errors
if foo
template "/etc/whatever.conf" do
...
end
end
not the same thing as
execute 'yum install httpd' do
not_if 'rpm -qa | grep -x httpd'
end
Not declarative
• Also, the Chef recipe with 100 bash or
powershell_script resource declarations
execute '/i/will/run/every/time' do
action :run
# because I don't have a guard here
end
Missing guards
default['mydaemon']['port'] = '1433'
# don't you mean the integer 1433?
default['mydaemon']['knob'] = 'disabled'
# don't you mean false?
Not using native Ruby data types
• If you use native data types you can validate
people’s input.
Fear of LWRPs
• Missed abstraction opportunities
• No good example to put here; they’re all 200 lines
long (thus proving my point)
remote_file 'whatever.tar.gz' do
source 'http://hardcoded.url.com/'
end
Hardcoded Strings
Excess Conditions & Recipe Length
• https://github.com/opscode-
cookbooks/mysql/blob/v3.0.12/recipes/server.rb
• (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
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"
Control Flow in Attributes
node['postgresql']['server']['packages'].each do |pg_pack|
package pg_pack
end
Common Recipe Code
• Easy to support more platforms without modifying
recipe
default.rb
server.rb
_suse.rb_fedora.rb_windows.rb
Separate recipes by OS
• If things you do are very different per platform,
separate them into different recipes
“Public” versus “Private” recipes
• ‘_’ faux-namespacing
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
Do not abuse compile-time
•.run_action(:must_die)
• Use sparingly, if at all!
if some_error_condition
fail "Helpful error message"
# rather than Chef::Application.fatal!("error")
end
Avoid poking Chef Internals
•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
git clone git://github.com/foozolix/foozolix.git
cd foozolix && ./configure
make
make install
Give people options for installation
• 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 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
Run System Commands Safely
• system
• backticks
•Chef::Mixin::ShellOut
•shell_out
•shell_out!
$ chef-apply -s
Chef::Recipe.send(:include, Chef::Mixin::ShellOut)
cmd = shell_out!("echo -n Ohai, world")
log cmd.stdout
^D
Recipe: (chef-apply cookbook)::(chef-apply recipe)
* log[Ohai, world] action write
Example Recipe Context
unless node.chef_environment('pigsty')
include_recipe 'bacon::default'
end
Feature Flags Example
if node['foo']['bar']['can_haz_bacon']
include_recipe 'bacon::default'
end
• Instead:
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
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
• Perfect for abstracting!
• Resource interface:
jboss_instance "petstore" do
instance_name "can_haz_cheezburgerz"
console_log_level "DEBUG"
datasources {'db1' => 'jdbc://whatever:5432/db1'}
end
Repetition == LWRP Candidate
• Write/debug hard logic once
• Clear consumer interface
• Parameter validation & sanity checking
• Non-JBoss experts can invoke without knowing gnarly details
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
Write helper libraries
• Create reusable helper functions in pure Ruby
• Move repetitive detail out of recipe context.
• http://tinyurl.com/chef-libraries
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
• Attribute Validator -
https://github.com/clintoncwolfe/attribute-validator
• You can also crib the 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...
Don’t Yet Know Chef?
• 2-Day Chef Fundamentals
Training in Boston
• June 16-17
• New Horizons, 75 Federal
St., Suite 1205
• Use code MEETUP to save
10%
Thank You!
E: jdunn@getchef.com
G: https://github.com/juliandunn
T: @julian_dunn
W: www.juliandunn.net
What Makes a Good Chef Cookbook? (May 2014 Edition)

More Related Content

What's hot

Infrastructure = Code
Infrastructure = CodeInfrastructure = Code
Infrastructure = Code
Georg Sorst
 
Cookbook testing with KitcenCI and Serverrspec
Cookbook testing with KitcenCI and ServerrspecCookbook testing with KitcenCI and Serverrspec
Cookbook testing with KitcenCI and Serverrspec
Daniel Paulus
 
Chef training - Day2
Chef training - Day2Chef training - Day2
Chef training - Day2
Andriy Samilyak
 
Chef training - Day3
Chef training - Day3Chef training - Day3
Chef training - Day3
Andriy Samilyak
 
Chef training Day5
Chef training Day5Chef training Day5
Chef training Day5
Andriy Samilyak
 
Chef training Day4
Chef training Day4Chef training Day4
Chef training Day4
Andriy Samilyak
 
Monitoring and tuning your chef server - chef conf talk
Monitoring and tuning your chef server - chef conf talk Monitoring and tuning your chef server - chef conf talk
Monitoring and tuning your chef server - chef conf talk
Andrew DuFour
 
Leveraging Ansible for CI/CD
Leveraging Ansible for CI/CDLeveraging Ansible for CI/CD
Leveraging Ansible for CI/CD
Shippable
 
Ansible new paradigms for orchestration
Ansible new paradigms for orchestrationAnsible new paradigms for orchestration
Ansible new paradigms for orchestration
Paolo Tonin
 
Ansible Introduction
Ansible Introduction Ansible Introduction
Ansible Introduction
Robert Reiz
 
Docker ansible-make-chef-puppet-unnecessary-minnihan
Docker ansible-make-chef-puppet-unnecessary-minnihanDocker ansible-make-chef-puppet-unnecessary-minnihan
Docker ansible-make-chef-puppet-unnecessary-minnihanjbminn
 
Deploying an application with Chef and Docker
Deploying an application with Chef and DockerDeploying an application with Chef and Docker
Deploying an application with Chef and Docker
Daniel Ku
 
Continuous infrastructure testing
Continuous infrastructure testingContinuous infrastructure testing
Continuous infrastructure testing
Daniel Paulus
 
Testable Infrastructure with Chef, Test Kitchen, and Docker
Testable Infrastructure with Chef, Test Kitchen, and DockerTestable Infrastructure with Chef, Test Kitchen, and Docker
Testable Infrastructure with Chef, Test Kitchen, and Docker
Mandi Walls
 
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Keith Resar
 
Chef for beginners module 5
Chef for beginners   module 5Chef for beginners   module 5
Chef for beginners module 5
Chef
 
Introduction to Ansible
Introduction to AnsibleIntroduction to Ansible
Introduction to Ansible
Michael Bahr
 
Zero Downtime Deployment with Ansible
Zero Downtime Deployment with AnsibleZero Downtime Deployment with Ansible
Zero Downtime Deployment with Ansible
Stein Inge Morisbak
 
Chef introduction
Chef introductionChef introduction
Chef introduction
FENG Zhichao
 
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Carlos Sanchez
 

What's hot (20)

Infrastructure = Code
Infrastructure = CodeInfrastructure = Code
Infrastructure = Code
 
Cookbook testing with KitcenCI and Serverrspec
Cookbook testing with KitcenCI and ServerrspecCookbook testing with KitcenCI and Serverrspec
Cookbook testing with KitcenCI and Serverrspec
 
Chef training - Day2
Chef training - Day2Chef training - Day2
Chef training - Day2
 
Chef training - Day3
Chef training - Day3Chef training - Day3
Chef training - Day3
 
Chef training Day5
Chef training Day5Chef training Day5
Chef training Day5
 
Chef training Day4
Chef training Day4Chef training Day4
Chef training Day4
 
Monitoring and tuning your chef server - chef conf talk
Monitoring and tuning your chef server - chef conf talk Monitoring and tuning your chef server - chef conf talk
Monitoring and tuning your chef server - chef conf talk
 
Leveraging Ansible for CI/CD
Leveraging Ansible for CI/CDLeveraging Ansible for CI/CD
Leveraging Ansible for CI/CD
 
Ansible new paradigms for orchestration
Ansible new paradigms for orchestrationAnsible new paradigms for orchestration
Ansible new paradigms for orchestration
 
Ansible Introduction
Ansible Introduction Ansible Introduction
Ansible Introduction
 
Docker ansible-make-chef-puppet-unnecessary-minnihan
Docker ansible-make-chef-puppet-unnecessary-minnihanDocker ansible-make-chef-puppet-unnecessary-minnihan
Docker ansible-make-chef-puppet-unnecessary-minnihan
 
Deploying an application with Chef and Docker
Deploying an application with Chef and DockerDeploying an application with Chef and Docker
Deploying an application with Chef and Docker
 
Continuous infrastructure testing
Continuous infrastructure testingContinuous infrastructure testing
Continuous infrastructure testing
 
Testable Infrastructure with Chef, Test Kitchen, and Docker
Testable Infrastructure with Chef, Test Kitchen, and DockerTestable Infrastructure with Chef, Test Kitchen, and Docker
Testable Infrastructure with Chef, Test Kitchen, and Docker
 
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
Ansible Automation Best Practices From Startups to Enterprises - Minnebar 12
 
Chef for beginners module 5
Chef for beginners   module 5Chef for beginners   module 5
Chef for beginners module 5
 
Introduction to Ansible
Introduction to AnsibleIntroduction to Ansible
Introduction to Ansible
 
Zero Downtime Deployment with Ansible
Zero Downtime Deployment with AnsibleZero Downtime Deployment with Ansible
Zero Downtime Deployment with Ansible
 
Chef introduction
Chef introductionChef introduction
Chef introduction
 
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
Infrastructure testing with Jenkins, Puppet and Vagrant - Agile Testing Days ...
 

Viewers also liked

Introduction to Docker & CoreOS - Symfony User Group Cologne
Introduction to Docker & CoreOS - Symfony User Group CologneIntroduction to Docker & CoreOS - Symfony User Group Cologne
Introduction to Docker & CoreOS - Symfony User Group Cologne
D
 
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.
 
Introduction to chef
Introduction to chefIntroduction to chef
Introduction to chef
Damith Kothalawala
 
Chef Cookbook Testing and Continuous Integration
Chef Cookbook Testing and Continuous IntegrationChef Cookbook Testing and Continuous Integration
Chef Cookbook Testing and Continuous Integration
Julian Dunn
 
Chef Fundamentals Training Series Module 1: Overview of Chef
Chef Fundamentals Training Series Module 1: Overview of ChefChef Fundamentals Training Series Module 1: Overview of Chef
Chef Fundamentals Training Series Module 1: Overview of ChefChef Software, Inc.
 
Introduction to Chef: Automate Your Infrastructure by Modeling It In Code
Introduction to Chef: Automate Your Infrastructure by Modeling It In CodeIntroduction to Chef: Automate Your Infrastructure by Modeling It In Code
Introduction to Chef: Automate Your Infrastructure by Modeling It In Code
Josh Padnick
 
Jenkins and Chef: Infrastructure CI and Automated Deployment
Jenkins and Chef: Infrastructure CI and Automated DeploymentJenkins and Chef: Infrastructure CI and Automated Deployment
Jenkins and Chef: Infrastructure CI and Automated Deployment
Dan Stine
 
Infrastructure Automation with Chef
Infrastructure Automation with ChefInfrastructure Automation with Chef
Infrastructure Automation with Chef
Adam Jacob
 
Chef Cookbook Workflow
Chef Cookbook WorkflowChef Cookbook Workflow
Chef Cookbook Workflow
Amazon Web Services
 
Introduction to Chef - Techsuperwomen Summit
Introduction to Chef - Techsuperwomen SummitIntroduction to Chef - Techsuperwomen Summit
Introduction to Chef - Techsuperwomen Summit
Jennifer Davis
 

Viewers also liked (10)

Introduction to Docker & CoreOS - Symfony User Group Cologne
Introduction to Docker & CoreOS - Symfony User Group CologneIntroduction to Docker & CoreOS - Symfony User Group Cologne
Introduction to Docker & CoreOS - Symfony User Group Cologne
 
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...
 
Introduction to chef
Introduction to chefIntroduction to chef
Introduction to chef
 
Chef Cookbook Testing and Continuous Integration
Chef Cookbook Testing and Continuous IntegrationChef Cookbook Testing and Continuous Integration
Chef Cookbook Testing and Continuous Integration
 
Chef Fundamentals Training Series Module 1: Overview of Chef
Chef Fundamentals Training Series Module 1: Overview of ChefChef Fundamentals Training Series Module 1: Overview of Chef
Chef Fundamentals Training Series Module 1: Overview of Chef
 
Introduction to Chef: Automate Your Infrastructure by Modeling It In Code
Introduction to Chef: Automate Your Infrastructure by Modeling It In CodeIntroduction to Chef: Automate Your Infrastructure by Modeling It In Code
Introduction to Chef: Automate Your Infrastructure by Modeling It In Code
 
Jenkins and Chef: Infrastructure CI and Automated Deployment
Jenkins and Chef: Infrastructure CI and Automated DeploymentJenkins and Chef: Infrastructure CI and Automated Deployment
Jenkins and Chef: Infrastructure CI and Automated Deployment
 
Infrastructure Automation with Chef
Infrastructure Automation with ChefInfrastructure Automation with Chef
Infrastructure Automation with Chef
 
Chef Cookbook Workflow
Chef Cookbook WorkflowChef Cookbook Workflow
Chef Cookbook Workflow
 
Introduction to Chef - Techsuperwomen Summit
Introduction to Chef - Techsuperwomen SummitIntroduction to Chef - Techsuperwomen Summit
Introduction to Chef - Techsuperwomen Summit
 

Similar to What Makes a Good Chef Cookbook? (May 2014 Edition)

What Makes a Good Cookbook?
What Makes a Good Cookbook?What Makes a Good Cookbook?
What Makes a Good Cookbook?
Julian Dunn
 
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
SmartLogic
 
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
Timur Batyrshin
 
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
sickill
 
Custom deployments with sbt-native-packager
Custom deployments with sbt-native-packagerCustom deployments with sbt-native-packager
Custom deployments with sbt-native-packager
GaryCoady
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
Lindsay Holmwood
 
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
Amazon Web Services
 
DB proxy server test: run tests on tens of virtual machines with Jenkins, Vag...
DB proxy server test: run tests on tens of virtual machines with Jenkins, Vag...DB proxy server test: run tests on tens of virtual machines with Jenkins, Vag...
DB proxy server test: run tests on tens of virtual machines with Jenkins, Vag...
Timofey Turenko
 
Dev ninja -> vagrant + virtualbox + chef-solo + git + ec2
Dev ninja  -> vagrant + virtualbox + chef-solo + git + ec2Dev ninja  -> vagrant + virtualbox + chef-solo + git + ec2
Dev ninja -> vagrant + virtualbox + chef-solo + git + ec2
Yros
 
Configuration management with Chef
Configuration management with ChefConfiguration management with Chef
Configuration management with Chef
Juan Vicente Herrera Ruiz de Alejo
 
Chef solo the beginning
Chef solo the beginning Chef solo the beginning
Chef solo the beginning
A.K.M. Ahsrafuzzaman
 
Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) Roundup
Wayne Carter
 
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
Antons Kranga
 
Automating Complex Setups with Puppet
Automating Complex Setups with PuppetAutomating Complex Setups with Puppet
Automating Complex Setups with Puppet
Kris Buytaert
 
Creating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesCreating Reusable Puppet Profiles
Creating Reusable Puppet Profiles
Bram Vogelaar
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统yiditushe
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet CampPuppet
 
Cloud Automation with Opscode Chef
Cloud Automation with Opscode ChefCloud Automation with Opscode Chef
Cloud Automation with Opscode Chef
Sri Ram
 
Chef patterns
Chef patternsChef patterns
Chef patterns
Biju Nair
 

Similar to What Makes a Good Chef Cookbook? (May 2014 Edition) (20)

What Makes a Good Cookbook?
What Makes a Good Cookbook?What Makes a Good Cookbook?
What Makes a Good Cookbook?
 
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
 
Cooking with Chef
Cooking with ChefCooking with Chef
Cooking with Chef
 
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
 
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
 
Custom deployments with sbt-native-packager
Custom deployments with sbt-native-packagerCustom deployments with sbt-native-packager
Custom deployments with sbt-native-packager
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
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
 
DB proxy server test: run tests on tens of virtual machines with Jenkins, Vag...
DB proxy server test: run tests on tens of virtual machines with Jenkins, Vag...DB proxy server test: run tests on tens of virtual machines with Jenkins, Vag...
DB proxy server test: run tests on tens of virtual machines with Jenkins, Vag...
 
Dev ninja -> vagrant + virtualbox + chef-solo + git + ec2
Dev ninja  -> vagrant + virtualbox + chef-solo + git + ec2Dev ninja  -> vagrant + virtualbox + chef-solo + git + ec2
Dev ninja -> vagrant + virtualbox + chef-solo + git + ec2
 
Configuration management with Chef
Configuration management with ChefConfiguration management with Chef
Configuration management with Chef
 
Chef solo the beginning
Chef solo the beginning Chef solo the beginning
Chef solo the beginning
 
Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) Roundup
 
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
 
Automating Complex Setups with Puppet
Automating Complex Setups with PuppetAutomating Complex Setups with Puppet
Automating Complex Setups with Puppet
 
Creating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesCreating Reusable Puppet Profiles
Creating Reusable Puppet Profiles
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
Cloud Automation with Opscode Chef
Cloud Automation with Opscode ChefCloud Automation with Opscode Chef
Cloud Automation with Opscode Chef
 
Chef patterns
Chef patternsChef patterns
Chef patterns
 

More from Julian Dunn

Technical Careers Beyond DevOps
Technical Careers Beyond DevOpsTechnical Careers Beyond DevOps
Technical Careers Beyond DevOps
Julian Dunn
 
Pull, Don't Push! Sensu Summit 2018 Talk
Pull, Don't Push! Sensu Summit 2018 TalkPull, Don't Push! Sensu Summit 2018 Talk
Pull, Don't Push! Sensu Summit 2018 Talk
Julian Dunn
 
Now That I Have Choreography, What Do I Do With It?
Now That I Have Choreography, What Do I Do With It?Now That I Have Choreography, What Do I Do With It?
Now That I Have Choreography, What Do I Do With It?
Julian Dunn
 
Distributed systems are hard; distributed systems of people are harder
Distributed systems are hard; distributed systems of people are harderDistributed systems are hard; distributed systems of people are harder
Distributed systems are hard; distributed systems of people are harder
Julian Dunn
 
Chef on AIX
Chef on AIXChef on AIX
Chef on AIX
Julian Dunn
 
Chef-NYC Announcements July 2014
Chef-NYC Announcements July 2014Chef-NYC Announcements July 2014
Chef-NYC Announcements July 2014
Julian Dunn
 
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
 
Improving Your Mac Productivity
Improving Your Mac ProductivityImproving Your Mac Productivity
Improving Your Mac Productivity
Julian 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
 
Chef and PowerShell Desired State Configuration
Chef and PowerShell Desired State ConfigurationChef and PowerShell Desired State Configuration
Chef and PowerShell Desired State Configuration
Julian Dunn
 
Configuration Management Isn't Everything
Configuration Management Isn't EverythingConfiguration Management Isn't Everything
Configuration Management Isn't Everything
Julian 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
 
ChefConf 2013: Beginner Chef Antipatterns
ChefConf 2013: Beginner Chef AntipatternsChefConf 2013: Beginner Chef Antipatterns
ChefConf 2013: Beginner Chef Antipatterns
Julian Dunn
 
Chef Workflow Strategies at SecondMarket
Chef Workflow Strategies at SecondMarketChef Workflow Strategies at SecondMarket
Chef Workflow Strategies at SecondMarket
Julian Dunn
 
What Your CDN Won't Tell You: Optimizing a News Website for Speed and Stability
What Your CDN Won't Tell You: Optimizing a News Website for Speed and StabilityWhat Your CDN Won't Tell You: Optimizing a News Website for Speed and Stability
What Your CDN Won't Tell You: Optimizing a News Website for Speed and Stability
Julian 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 Shell
Julian Dunn
 

More from Julian Dunn (16)

Technical Careers Beyond DevOps
Technical Careers Beyond DevOpsTechnical Careers Beyond DevOps
Technical Careers Beyond DevOps
 
Pull, Don't Push! Sensu Summit 2018 Talk
Pull, Don't Push! Sensu Summit 2018 TalkPull, Don't Push! Sensu Summit 2018 Talk
Pull, Don't Push! Sensu Summit 2018 Talk
 
Now That I Have Choreography, What Do I Do With It?
Now That I Have Choreography, What Do I Do With It?Now That I Have Choreography, What Do I Do With It?
Now That I Have Choreography, What Do I Do With It?
 
Distributed systems are hard; distributed systems of people are harder
Distributed systems are hard; distributed systems of people are harderDistributed systems are hard; distributed systems of people are harder
Distributed systems are hard; distributed systems of people are harder
 
Chef on AIX
Chef on AIXChef on AIX
Chef on AIX
 
Chef-NYC Announcements July 2014
Chef-NYC Announcements July 2014Chef-NYC Announcements July 2014
Chef-NYC Announcements July 2014
 
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
 
Improving Your Mac Productivity
Improving Your Mac ProductivityImproving Your Mac Productivity
Improving Your Mac Productivity
 
Chef Cookbook Governance BoF at ChefConf
Chef Cookbook Governance BoF at ChefConfChef Cookbook Governance BoF at ChefConf
Chef Cookbook Governance BoF at ChefConf
 
Chef and PowerShell Desired State Configuration
Chef and PowerShell Desired State ConfigurationChef and PowerShell Desired State Configuration
Chef and PowerShell Desired State Configuration
 
Configuration Management Isn't Everything
Configuration Management Isn't EverythingConfiguration Management Isn't Everything
Configuration Management Isn't Everything
 
An Introduction to DevOps with Chef
An Introduction to DevOps with ChefAn Introduction to DevOps with Chef
An Introduction to DevOps with Chef
 
ChefConf 2013: Beginner Chef Antipatterns
ChefConf 2013: Beginner Chef AntipatternsChefConf 2013: Beginner Chef Antipatterns
ChefConf 2013: Beginner Chef Antipatterns
 
Chef Workflow Strategies at SecondMarket
Chef Workflow Strategies at SecondMarketChef Workflow Strategies at SecondMarket
Chef Workflow Strategies at SecondMarket
 
What Your CDN Won't Tell You: Optimizing a News Website for Speed and Stability
What Your CDN Won't Tell You: Optimizing a News Website for Speed and StabilityWhat Your CDN Won't Tell You: Optimizing a News Website for Speed and Stability
What Your CDN Won't Tell You: Optimizing a News Website for Speed and Stability
 
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
 

Recently uploaded

Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 

Recently uploaded (20)

Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 

What Makes a Good Chef Cookbook? (May 2014 Edition)

  • 1. What Makes a Good Cookbook? Julian C. Dunn Senior Consulting Engineer Engineering Team Lead Chef Software, Inc. <jdunn@getchef.com>
  • 2. $ whoami • Consulting Engineer Engineering Team Lead at Chef • System Administrator • Reformed Java Developer • Writes silly code like this •https://github.com/juliandunn/ doge-chef-formatter
  • 3. Finding a Good Cookbook LMGTCFY
  • 4.
  • 5. Do judge a cookbook by its cover
  • 6.
  • 7.
  • 8.
  • 9.
  • 10. 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 Too Clever for Its Own Good
  • 11. 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(' ')) Poking at Chef Internals • Other abuses: Messing with run_context and run_state
  • 12. if node.run_list.recipes.include?('foo::bar') ... end Poking run_list and environment if node.chef_environment == 'production' ... end • Use feature flags!
  • 13. template "/etc/whatever.conf" do ... not_if { foo } end Compile vs. Execute Errors if foo template "/etc/whatever.conf" do ... end end not the same thing as
  • 14. execute 'yum install httpd' do not_if 'rpm -qa | grep -x httpd' end Not declarative • Also, the Chef recipe with 100 bash or powershell_script resource declarations
  • 15. execute '/i/will/run/every/time' do action :run # because I don't have a guard here end Missing guards
  • 16. default['mydaemon']['port'] = '1433' # don't you mean the integer 1433? default['mydaemon']['knob'] = 'disabled' # don't you mean false? Not using native Ruby data types • If you use native data types you can validate people’s input.
  • 17. Fear of LWRPs • Missed abstraction opportunities • No good example to put here; they’re all 200 lines long (thus proving my point)
  • 18. remote_file 'whatever.tar.gz' do source 'http://hardcoded.url.com/' end Hardcoded Strings
  • 19. Excess Conditions & Recipe Length • https://github.com/opscode- cookbooks/mysql/blob/v3.0.12/recipes/server.rb • (We’ve since refactored this)
  • 21. Put control flow in attributes • Especially for cross-platform cookbooks • Set common set of attributes, write common behavior in recipe context
  • 22. 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" Control Flow in Attributes
  • 23. node['postgresql']['server']['packages'].each do |pg_pack| package pg_pack end Common Recipe Code • Easy to support more platforms without modifying recipe
  • 24. default.rb server.rb _suse.rb_fedora.rb_windows.rb Separate recipes by OS • If things you do are very different per platform, separate them into different recipes
  • 25. “Public” versus “Private” recipes • ‘_’ faux-namespacing
  • 26. 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 Do not abuse compile-time •.run_action(:must_die) • Use sparingly, if at all!
  • 27. if some_error_condition fail "Helpful error message" # rather than Chef::Application.fatal!("error") end Avoid poking Chef Internals •Chef::Application.fatal is for use by Chef itself •fail or raise is better
  • 28. 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
  • 29. git clone git://github.com/foozolix/foozolix.git cd foozolix && ./configure make make install Give people options for installation • At least give people a way to install from packages. • “Compile from source” should be banned in most cases.
  • 30. Be declarative • Know and use built-in Chef resources • Know where to find LWRPs to avoid batch/execute/powershell_script • Consider 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
  • 31. Run System Commands Safely • system • backticks •Chef::Mixin::ShellOut •shell_out •shell_out!
  • 32. $ chef-apply -s Chef::Recipe.send(:include, Chef::Mixin::ShellOut) cmd = shell_out!("echo -n Ohai, world") log cmd.stdout ^D Recipe: (chef-apply cookbook)::(chef-apply recipe) * log[Ohai, world] action write Example Recipe Context
  • 33. unless node.chef_environment('pigsty') include_recipe 'bacon::default' end Feature Flags Example if node['foo']['bar']['can_haz_bacon'] include_recipe 'bacon::default' end • Instead:
  • 34. 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
  • 35. 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 • Perfect for abstracting! • Resource interface:
  • 36. jboss_instance "petstore" do instance_name "can_haz_cheezburgerz" console_log_level "DEBUG" datasources {'db1' => 'jdbc://whatever:5432/db1'} end Repetition == LWRP Candidate • Write/debug hard logic once • Clear consumer interface • Parameter validation & sanity checking • Non-JBoss experts can invoke without knowing gnarly details
  • 37. 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 Write helper libraries • Create reusable helper functions in pure Ruby • Move repetitive detail out of recipe context. • http://tinyurl.com/chef-libraries
  • 38. 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
  • 39. Use Community Helpers • Chef Sugar - http://code.sethvargo.com/chef-sugar/ • Chef Cutlery - https://github.com/realityforge/chef-cutlery • Attribute Validator - https://github.com/clintoncwolfe/attribute-validator • You can also crib the ideas if you want to avoid external dependencies
  • 41. 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
  • 42. Make your code aromatic • Keep recipes small • Keep recipes simple • Use a consistent style • Use Foodcritic
  • 43. 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
  • 44. 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...
  • 45. Don’t Yet Know Chef? • 2-Day Chef Fundamentals Training in Boston • June 16-17 • New Horizons, 75 Federal St., Suite 1205 • Use code MEETUP to save 10%
  • 46. Thank You! E: jdunn@getchef.com G: https://github.com/juliandunn T: @julian_dunn W: www.juliandunn.net