SlideShare ist ein Scribd-Unternehmen logo
1 von 121
Downloaden Sie, um offline zu lesen
Cookbook Design Patterns
 Speaker:

 Joshua Timberman Sr. Technical Evangelist
      ‣ joshua@opscode.com
      ‣ @jtimberman
      ‣ www.opscode.com
                           Copyright © 2010 Opscode, Inc - All Rights Reserved   1
Thursday, March 17, 2011

Welcome
Copyright © 2010 Opscode, Inc - All Rights Reserved
                           http://www.flickr.com/photos/anotherphotograph/2100904507/sizes/o/   2
Thursday, March 17, 2011
cider:~/dev/cookbooks% git log | grep -ic "timberman"
      950



                           Copyright © 2010 Opscode, Inc - All Rights Reserved   3
Thursday, March 17, 2011

I write cookbooks
Copyright © 2010 Opscode, Inc - All Rights Reserved   4
Thursday, March 17, 2011

Training, services and evangelism
Developers?
   Systems Administrators?
   Developers who do system
   administration?
   “Business” People?



                                                                                      http://www.flickr.com/photos/timyates/2854357446/sizes/l/

                                Copyright © 2010 Opscode, Inc - All Rights Reserved                                                              5
Thursday, March 17, 2011

Enough about me, who are you?
Copyright © 2010 Opscode, Inc - All Rights Reserved   6
Thursday, March 17, 2011

Lets talk about chef
http://www.flickr.com/photos/tambako/4444066932/
                                  Copyright © 2010 Opscode, Inc - All Rights Reserved   7
Thursday, March 17, 2011

Show of hands time! How many people....
...solo?

                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   8
Thursday, March 17, 2011

Who is using chef solo, Directly on your own or through a service like EY?
...server?

                                   Copyright © 2010 Opscode, Inc - All Rights Reserved   9
Thursday, March 17, 2011

Who’s using their own Open Source chef server?
...Platform?

                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   10
Thursday, March 17, 2011

Who is using the Opscode Platform?
Chef enables infrastructure as code
           Manage configuration as idempotent Resources.
           Put them together in Recipes.
           Track it like Source Code.
           Configure your servers.

                           package "haproxy" do
                             action :install
                           end

                           template "/etc/haproxy/haproxy.cfg" do
                             source "haproxy.cfg.erb"
                             owner "root"
                             group "root"
                             mode 0644
                             notifies :restart, "service[haproxy]"
                           end

                           service "haproxy" do
                             action [:enable, :start]
                           end

                                      Copyright © 2010 Opscode, Inc - All Rights Reserved   11
Thursday, March 17, 2011

This isn’t a talk about how Chef works or the nitty gritty, we assume that you have some
familiarity with Chef already. And there’s lots of resources for learning :).
wiki.opscode.com
             help.opscode.com
           joshua@opscode.com
                @jtimberman



                                                                                         http://www.flickr.com/photos/38299630@N05/3635356091/




                                   Copyright © 2010 Opscode, Inc - All Rights Reserved                                                          12
Thursday, March 17, 2011

If you want to know more, find me
Chef provides an MVC
               framework


                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   13
Thursday, March 17, 2011

Chef is an MVC framework for building infrastructure. How is that?
{
  "kernel": {
    "machine": "x86_64",
    "name": "Darwin",
    "os": "Darwin",
    "version": "Darwin Kernel Version 10.4.0: Fri Apr 23 18:28:53
PDT 2010; root:xnu-1504.7.4~1/RELEASE_I386",
    "release": "10.4.0"
  },

       Node attributes are the
  "platform_version": "10.6.4",
  "platform": "mac_os_x",
  "platform_build": "10F569",


               model
  "domain": "local",
  "os": "darwin",
  "current_user": "jtimberman",
  "ohai_time": 1278602661.60043,
  "os_version": "10.4.0",
  "uptime": "18 days 17 hours 49 minutes 18 seconds",
  "ipaddress": "10.13.37.116",
  "hostname": "cider",
  "fqdn": "cider.local",
  "uptime_seconds": 1619358
}
                                    Copyright © 2010 Opscode, Inc - All Rights Reserved    14
Thursday, March 17, 2011

Models are data. Attributes are data. We’re going to process and mold the data to get to
where we want to be.
A configured node is the
          view
                                   Copyright © 2010 Opscode, Inc - All Rights Reserved   http://www.flickr.com/photos/peterrosbjerg/3913766224/   15
Thursday, March 17, 2011

And where we want to be is a configured node. Running a Rails app, database, middleware,
whatever.
Recipes are the
                             controller


                                   http://www.flickr.com/photos/roadsidepictures/2478953342/sizes/o/
                                        Copyright © 2010 Opscode, Inc - All Rights Reserved           16
Thursday, March 17, 2011

They do all the processing of the data to build the view.
Recipes are Ruby.




                                      Copyright © 2010 Opscode, Inc - All Rights Reserved   http://www.flickr.com/photos/thisisbossi/3526698689/   17
Thursday, March 17, 2011

Since recipes are Ruby, that gives us a lot of power and flexibility.
Cookbooks are
                 packages of recipes


                                    http://www.flickr.com/photos/riggenransom/4140166239
                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   18
Thursday, March 17, 2011

Recipes and supporting code, assets, etc.
Design patterns are
  applicable to cookbooks


                                     Copyright © 2010 Opscode, Inc - All Rights Reserved      19
Thursday, March 17, 2011

Since recipes and other things are code, and we’re really talking about infrastructure as code,
there’s good design patterns!
Cookbooks represent
              best practices.


                           Copyright © 2010 Opscode, Inc - All Rights Reserved   20
Thursday, March 17, 2011
Best practices are
                           opinions.


                             Copyright © 2010 Opscode, Inc - All Rights Reserved   21
Thursday, March 17, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved   http://www.flickr.com/photos/peyri/304354485
                                                                                                                             22
Thursday, March 17, 2011

So lets talk about cookbooks
Copyright © 2010 Opscode, Inc - All Rights Reserved   23
Thursday, March 17, 2011

Of course I really mean Opscode’s cookbooks
Copyright © 2010 Opscode, Inc - All Rights Reserved   24
Thursday, March 17, 2011

Question: fork/clone/watch? Thanks!
Contributed? You’re awesome, thank you!
Tried to contribute and I told you to sign a CLA? Apache license requirement
http://www.opscode.com/blog/2009/08/11/why-we-
              chose-the-apache-license/




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   25
Thursday, March 17, 2011

Please sign a CLA, its for you as much for us
Copyright © 2010 Opscode, Inc - All Rights Reserved       26
Thursday, March 17, 2011

This is the important part: it doesn’t assign copyright to Opscode, you enable us to bundle
and redistribute your work, which means your code reaches a lot of people, yay!
Copyright © 2010 Opscode, Inc - All Rights Reserved   27
Thursday, March 17, 2011

But you can also have your code reach a lot of people through Opscode’s Chef Community
site: Its like RubyGems for Chef cookbooks. You don’t need to sign a CLA.

Its also easier to find cookbooks than trawling through github.
Cookbooks package configuration

   README
   attributes/
   definitions/
   files/
   libraries/
   metadata.rb
   providers/
   recipes/
   resources/
   templates/
                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   28
Thursday, March 17, 2011

Cookbooks can have a bunch of stuff in them. Lets talk about this stuff.
Copyright © 2010 Opscode, Inc - All Rights Reserved         29
Thursday, March 17, 2011

Question: Who saw this blog post?

It talks about how writing your readme first to get clarity about the code, plus it gives a nice
bit of documentation.
No really, write the fine
               manual.



                           http://www.flickr.com/photos/bike/2263136517
                           Copyright © 2010 Opscode, Inc - All Rights Reserved   30
Thursday, March 17, 2011
Writing Recipes



                                   Copyright © 2010 Opscode, Inc - All Rights Reserved   31
Thursday, March 17, 2011

Okay, you got writing the README out of the way, or maybe you didn’t. Now write the
recipes.
Contrived Example



                           Copyright © 2010 Opscode, Inc - All Rights Reserved   32
Thursday, March 17, 2011

A real world example
Copyright © 2010 Opscode, Inc - All Rights Reserved   33
Thursday, March 17, 2011

So I was at FOSDEM this year. Did anyone go?

Fosdem is a huge free conference in Europe, 5000+ people, 300 talks, 2 days.
GNU parallel

                           http://www.gnu.org/software/parallel/

                                     It replaces xargs




                                       Copyright © 2010 Opscode, Inc - All Rights Reserved   34
Thursday, March 17, 2011

One of the 300 talks was on GNU parallel.
I wrote a cookbook
                       during the talk.
                           http://www.flickr.com/photos/jenorton/2229437427/
                             Copyright © 2010 Opscode, Inc - All Rights Reserved   35
Thursday, March 17, 2011
This isn’t because I’m
                 awesome.


                           Copyright © 2010 Opscode, Inc - All Rights Reserved   36
Thursday, March 17, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
                                     http://www.flickr.com/photos/flikr/131433774/          37
Thursday, March 17, 2011

Cats with laser eyes are awesome.
Nor because the talk
                   was boring.


                           Copyright © 2010 Opscode, Inc - All Rights Reserved   38
Thursday, March 17, 2011
I wanted to write one
                    anyway.


                           Copyright © 2010 Opscode, Inc - All Rights Reserved   39
Thursday, March 17, 2011
GNU Parallel is like almost any GNU software.

        wget ftp://ftp.gnu.org/gnu/thing/thing.tar.gz
        tar -zxvf thing.tar.gz
        cd thing
        ./configure && make && make install
        Rejoice!




                             Copyright © 2010 Opscode, Inc - All Rights Reserved   40
Thursday, March 17, 2011
Do that in a recipe



remote_file "/tmp/parallel-20110205.tar.bz2" do
  source "http://ftp.gnu.org/gnu/parallel/parallel-20110205.tar.bz2"
end

bash "build gnu parallel from source" do
  cwd "/tmp"
  code <<-EOF
  tar -jxvf parallel-20110205.tar.bz2
  (cd parallel-20110205 && ./configure)
  (cd parallel-20110205 && make && make install)
  EOF
end




                           Copyright © 2010 Opscode, Inc - All Rights Reserved   41
Thursday, March 17, 2011

So do that in a recipe.
That wasn’t hard.



                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   42
Thursday, March 17, 2011

Big deal, thats not hard. I can do that in about 42 seconds. And I did.
But thats a horrible
                          recipe.


                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   43
Thursday, March 17, 2011

Not because it installs from source. Unless..
'-.                   .-'
                           _______________'-._________.-'______________
                           '-.              _     '-. .-'     _              .-'
                               '-.         (_) /         (_)            .-'
                                   '-.          /                   .-'
                                       '-.____/             ____.-'
                                              _ _ _ _ _ /
                                          //////////
                                         ///////////
                                        |||| .-----------._||||
                                        |||| '-|___|___|-' ||||
                                         '---------' ////
                                          |||||||||||||///
                                            ///////
                                              /////             jnh




                                          http://triple-double-u.com/ascii/?s=ascii-art&y=weather&q=ab/beard.txt
                                                             http://ascii-art.de/info/copyright/
                                                   Copyright © 2010 Opscode, Inc - All Rights Reserved             44
Thursday, March 17, 2011

Unless you have a unix sysadmin beard :) and package everything.
Really, why is it bad?



                           Copyright © 2010 Opscode, Inc - All Rights Reserved   45
Thursday, March 17, 2011
remote_file problems
   Can’t download from a different location!
   Can’t download a different version!
   The file gets downloaded every time to verify the checksum.

   Use customizable attributes

  remote_file "/tmp/parallel-20110205.tar.bz2" do
    source "http://ftp.gnu.org/gnu/parallel/parallel-20110205.tar.bz2"
  end




                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   46
Thursday, March 17, 2011

This resource doesn’t have an easy way for someone to customize the location, or the
version, and the file has to be downloaded in order to verify the checksum every time.
Design Pattern 1:
                              Attributes


                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   47
Thursday, March 17, 2011

So we reach our first design pattern, use attributes.
In cookbooks/gnu_parallel/attributes/default.rb:


    default['gnu_parallel']['url'] = 'http://ftp.gnu.org/gnu/parallel'
    default['gnu_parallel']['version'] = '20110205'
    default['gnu_parallel']['checksum'] = 'sha256s dont fit on slides'




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   48
Thursday, March 17, 2011

Wait, but I know what versions, and urls and everything in my infrastructure.

Yeah but if you want to share that, random folks on the internet don’t have the same
infrastructure.
/tmp isn’t a great location
   Some systems clear it on reboot.
   This causes the file to be downloaded again.
   Use Chef::Config[:file_cache_path].




                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   49
Thursday, March 17, 2011

Downloading to /tmp isn’t a great solution either.
Design Pattern 2:
                Exploit Chef internal
                       values

                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   50
Thursday, March 17, 2011

Second pattern, leverage the ability to access Chef’s Ruby objects in Recipes.
remote_file using attributes




version = node['gnu_parallel']['version']
cache_path = Chef::Config[:file_cache_path]

remote_file "#{cache_path}/parallel-#{version}.tar.bz2" do
  source "#{node['gnu_parallel']['url']}/parallel-#{version}.tar.bz2"
  checksum node['gnu_parallel']['checksum']
  mode 0644
end




                                    Copyright © 2010 Opscode, Inc - All Rights Reserved     51
Thursday, March 17, 2011

So now we have a remote file resource that uses some attributes, and internal Chef values.
bash script problems
                           bash "build gnu parallel from source" do
                             cwd "/tmp"
                             code <<-EOF
                             tar -jxvf parallel-20110205.tar.bz2
                             (cd parallel-20110205 && ./configure)
                             (cd parallel-20110205 && make && make install)
                             EOF
                           end




                       Least of all is compiling from source :-)


                                           Copyright © 2010 Opscode, Inc - All Rights Reserved   52
Thursday, March 17, 2011

The other resource in the recipe has problems.
bash script solutions!
   The version needs to be an attribute.
   The default configure options may not be useful.
        Moar attributes.

                           default['gnu_parallel']['configure_options'] = []




                                            Copyright © 2010 Opscode, Inc - All Rights Reserved   53
Thursday, March 17, 2011

We should reuse the version attribute, which we saw earlier. What if we want to customize
how things are compiled, or the install prefix?

Define that as an attribute and set it to an empty array, user can modify the attribute in a role
or on the node.
Design Pattern 3: Sane
     defaults easily changed


                                   Copyright © 2010 Opscode, Inc - All Rights Reserved   54
Thursday, March 17, 2011

Empty configure options is sane because there aren’t any of those enabled when you do a
normal ./configure when compiling from source.
bash script using attributes



config_opts = node['gnu_parallel']['configure_options'].join(" ")

bash "build gnu parallel" do
  cwd Chef::Config[:file_cache_path]
  code <<-EOF
  tar -jxvf parallel-#{version}.tar.bz2
  (cd parallel-#{version} && ./configure #{config_opts})
  (cd parallel-#{version} && make && make install)
  EOF
end




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved      55
Thursday, March 17, 2011

So here we add a little more ruby, but gain a lot more flexibility. We’re Rubyists, so we’re not
scared of Ruby.
'-.                   .-'
                           _______________'-._________.-'______________
                           '-.              _     '-. .-'     _              .-'
                               '-.         (_) /         (_)            .-'
                                   '-.          /                   .-'
                                       '-.____/             ____.-'
                                              _ _ _ _ _ /
                                          //////////
                                         ///////////
                                        |||| .-----------._||||
                                        |||| '-|___|___|-' ||||
                                         '---------' ////
                                          |||||||||||||///
                                            ///////
                                              /////             jnh




                                          http://triple-double-u.com/ascii/?s=ascii-art&y=weather&q=ab/beard.txt
                                                             http://ascii-art.de/info/copyright/
                                                   Copyright © 2010 Opscode, Inc - All Rights Reserved             56
Thursday, March 17, 2011

The README tells his guy how to modify the attributes to customize how to configure and
where to install.

... Of course he’s going to make a package anyway.
Attribute conditional on platform in attributes file
                             case node['platform']
                             when "centos"
                               default['gnu_parallel']['install_method'] = 'package'
                             else
                               default['gnu_parallel']['install_method'] = 'source'
                             end




                            cookbooks/gnu_parallel/default.rb

include_recipe "gnu_parallel::#{node['gnu_parallel']['install_method']}"



                           cookbooks/gnu_parallel/package.rb

                                           package "gnu-parallel"


                                              Copyright © 2010 Opscode, Inc - All Rights Reserved   57
Thursday, March 17, 2011

Select which recipe to use based on platform, on centos we’ll install from package using the
package recipe
Design Pattern 12:
                       Platform specific
                         conditionals

                                      Copyright © 2010 Opscode, Inc - All Rights Reserved      58
Thursday, March 17, 2011

Its good to utilize chef’s ability to look up the node’s platform and select behavior or set
attributes based on the platform.
INFO: remote_file[/var/cache/chef/parallel-20110205.tar.bz2]:
Creating /var/cache/chef/parallel-20110205.tar.bz2
INFO: Setting mode to 644 for remote_file[/var/cache/chef/
parallel-20110205.tar.bz2]
INFO: Ran bash[build gnu parallel] successfully




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved    59
Thursday, March 17, 2011

All that said, we can run chef on the node and get the source installed gnu-parallel, and
share this cookbook with other users who can use it how they wish. Yay!
All that in ~30 minutes



                           Copyright © 2010 Opscode, Inc - All Rights Reserved   60
Thursday, March 17, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
                                      http://www.flickr.com/photos/flikr/131433774/          61
Thursday, March 17, 2011

Because I really am a Cat with Laser Eyes!
Copyright © 2010 Opscode, Inc - All Rights Reserved
                                      http://www.flickr.com/photos/rutty/438775617          62
Thursday, March 17, 2011

Here’s a giant rubber duck. Quack.
Recipes



                                    Copyright © 2010 Opscode, Inc - All Rights Reserved      63
Thursday, March 17, 2011

Lets talk about Recipes a bit more. We saw a contrived example recipe, lets look at how to
best to utilize recipes in cookbooks. These are where we formulate our opinions.
Recipes

   Separate by functionality
        default
        client
        server
        ... etc




                                      Copyright © 2010 Opscode, Inc - All Rights Reserved       64
Thursday, March 17, 2011

It is totally okay to have separate recipes split up by functionality of what they’re configuring.
We saw some of this with the package vs source recipes earlier.
Recipes

   Avoid hardcoding data
        node attributes
        data bags
        chef search




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved     65
Thursday, March 17, 2011

Chef has a rich set of features that allow us to avoid hardcoding data in recipes

In addition to attributes that we saw earlier, when using the Chef Server we can use data bags
and search.
Code Reuse!




                             http://www.flickr.com/photos/dnorman/3314634378
                               Copyright © 2010 Opscode, Inc - All Rights Reserved   66
Thursday, March 17, 2011

Reduce, reuse, recycle.
Design Pattern 4:
                           Separate recipes


                                Copyright © 2010 Opscode, Inc - All Rights Reserved   67
Thursday, March 17, 2011
Separate by functionality

   default.rb

   client.rb

   server.rb



                                      Copyright © 2010 Opscode, Inc - All Rights Reserved   68
Thursday, March 17, 2011

default - install common components, should do what one might expect
client - set up to talk to a server, use search to find the server based on a role
server - set up the server part, search to find clients
Our Nagios cookbook
            uses this pattern.




                            http://www.flickr.com/photos/cote/163746456
                           Copyright © 2010 Opscode, Inc - All Rights Reserved   69
Thursday, March 17, 2011
%w{
              nagios-nrpe-server
              nagios-plugins
              nagios-plugins-basic
              nagios-plugins-standard
            }.each do |pkg|
              package pkg
            end

            remote_directory "/usr/lib/nagios/plugins" do
              source "plugins"
              owner "nagios"
              group "nagios"
              mode 0755
              files_mode 0755
            end



                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   70
Thursday, March 17, 2011

nagios::default, packages and plugins.
Copyright © 2010 Opscode, Inc - All Rights Reserved
                                   http://www.flickr.com/photos/zigazou76/3702501888         71
Thursday, March 17, 2011

Danger!

We’re going to talk about some Chef Server features.
search(:node, "role:#{node[:nagios][:server_role]}") do |n|
    mon_host << n['ipaddress']
  end

  package "nagios-nrpe-server"

  template "/etc/nagios/nrpe.cfg" do
    source "nrpe.cfg.erb"
    owner "nagios"
    group "nagios"
    mode "0644"
    variables :mon_host => mon_host
    notifies :restart, "service[nagios-nrpe-server]"
  end

  service "nagios-nrpe-server" do
    action [:enable,:start]
  end



                                     Copyright © 2010 Opscode, Inc - All Rights Reserved      72
Thursday, March 17, 2011

nagios::client is a bit more interesting, where we search for the system that is the monitoring
server and then allow it to connect.
include_recipe "nagios::client"

                       nodes = search(:node, "hostname:*")

                       package "nagios3"

                       template "/etc/nagios3/hosts.cfg" do
                         source "hosts.cfg.erb"
                         owner "nagios"
                         group "nagios"
                         mode 0644
                         variables :nodes => nodes
                         notifies :restart, "service[nagios3]"
                       end

                       service "nagios3" do
                         action [ :enable, :start]
                       end

                                      Copyright © 2010 Opscode, Inc - All Rights Reserved   73
Thursday, March 17, 2011

Similiarly in nagios::server we search for all the nodes to monitor.
But I use Chef Solo.



                                      Copyright © 2010 Opscode, Inc - All Rights Reserved   74
Thursday, March 17, 2011

So all thats wonderful if you’re using a Server. But you’re not. You’re using Solo.
Benefits of Chef Server

   Persistent node data
   Arbitrary infrastructure data
   Search indexes
   API




                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   75
Thursday, March 17, 2011

A sidebar about solo vs server flexibility and reuse you might be missing.
Design Pattern 6L:
               Check for Chef Solo.


                           Copyright © 2010 Opscode, Inc - All Rights Reserved   76
Thursday, March 17, 2011
if Chef::Config[:solo]
                             node_list = nodes['mything']['node_list']
                           else
                             node_list = search(:node, "role:mything")
                           end




                                          Copyright © 2010 Opscode, Inc - All Rights Reserved   77
Thursday, March 17, 2011

Make a conditional check for solo before doing something like a search, or loading from a
data bag or other server-only feature.
Hardcoding data: Anti-pattern

   Customizable cookbooks
   Document default attributes
        README!

   Let users override with roles
   Abstract to data bags
        non-role/non-node specific like application info

   Play nice with chef-solo

                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   78
Thursday, March 17, 2011

Hardcoding recipes is an anti pattern. We already saw this.
Templates and Files



                                   Copyright © 2010 Opscode, Inc - All Rights Reserved    79
Thursday, March 17, 2011

Lets talk about some of the good things you can do with cookbook assets - templates and
files
File specificity

        cookbooks/mysql/templates
                    centos/
                    debian/
                    default/
                    redhat/
                    ubuntu-10.04/
                    ubuntu-8.04/
                    ubuntu-9.10/
           all contain my.cnf.erb
           rendered template picked based on node’s platform




                                      Copyright © 2010 Opscode, Inc - All Rights Reserved         80
Thursday, March 17, 2011

File specificity is useful if your environment has multiple platforms, or if you’re using
cookbooks from others that support platforms different than your own.

Generally, install the package, grab the default config file and stick it in the right directory.
Static vs Dynamic Resources

        cookbook_file is static
        template is dynamic

           Duh :).




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   81
Thursday, March 17, 2011

In recipes, use the appropriate resources.
You want dynamic

        Easily sharable
        Data driven
        Rich data from multiple sources




                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   82
Thursday, March 17, 2011

So you want templates. Use them. They’re ERB, so <3 for Rubyists. And they help others
customize your cookbook for their environment with attributes, of course
Libraries, Definitions,
                Resources and
                   Providers

                                     Copyright © 2010 Opscode, Inc - All Rights Reserved       83
Thursday, March 17, 2011

Cookbooks are more than just recipes and assets (and attributes). Lets talk about libraries,
definitions, resources and providers.
Libraries

   Recipe helpers
   LWRP helpers
   Heavyweight R/P




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   84
Thursday, March 17, 2011

Extend chef with libraries, like enhance recipes with helpers.
Recipe Helpers
   Use Chef::Recipe class
   Methods are available directly in recipes

                           # in the library
                           class Chef
                             class Recipe
                               def radiant_edge?
                                 node[:radiant][:edge]
                               end
                             end
                           end

                           # in the recipe
                           if radiant_edge?
                             deploy "/srv/radiant" do
                               repository "git://github.com/radiant/radiant.git"
                             end
                           end




                                           Copyright © 2010 Opscode, Inc - All Rights Reserved   85
Thursday, March 17, 2011

Extend the Chef::Recipe class.
LWRP Helpers
   Don’t repeat yourself!
   Abstract API calls

                           module Opscode
                             module Aws
                               module Ec2
                                 def ec2
                                   @@ec2 ||= RightAws::Ec2.new(
                                        new_resource.aws_access_key,
                                        new_resource.aws_secret_access_key,
                                        { :logger => Chef::Log }
                                     )
                                 end
                               end
                             end
                           end

                           # in provider:
                           include Opscode::Aws::Ec2
                           ...
                             ec2.describe_addresses.find{|a| a[:public_ip] == ip}
                           ...


                                            Copyright © 2010 Opscode, Inc - All Rights Reserved   86
Thursday, March 17, 2011

in our aws cookbook
Heavyweight Resources & Providers

        Full Ruby classes like those in
        Chef itself
        Allow behaviors not available in
        LWRPs
            ‣ inherit/extend existing resources/provider
        Distribute as gems
            ‣ chef-deploy



                                   Copyright © 2010 Opscode, Inc - All Rights Reserved   87
Thursday, March 17, 2011

Sometimes you might want to write full resources and provides.
Definitions



                                   http://www.flickr.com/photos/thestorylady/4326274437
                                       Copyright © 2010 Opscode, Inc - All Rights Reserved   88
Thursday, March 17, 2011

Don’t use definitions anymore. They look like resources, but they’re actually replaced by the
resources they contain and they don’t send/receive notifications. Instead for more awesome,
use...
Lightweight Resources
            & Providers


                                   http://www.flickr.com/photos/lucynieto/2769594798
                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   89
Thursday, March 17, 2011

Aka LWRPs, these are a lightweight DSL for creating new resources and providers in your
cookbooks.
Resource DSL

   actions
   attributes
        validation parameters




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   90
Thursday, March 17, 2011

Resources really just contain two things, actions and attributes.
Validation Parameters
                                        http://bit.ly/cheflwrp

                               Option                                                    Meaning

                              :default                                             Default value

                              :kind_of                     Value must be a kind_of?(Klass)

                              :required                   Raise exception if this is missing

                               :regex           Match the value with regular expression

                              :equal_to                                     Value must match.

                           :name_attribute                Set to the name of the resource.

                             :callbacks                 Hash of Procs, should return true.

                            :respond_to          Ensure the value has the given method.


                                             Copyright © 2010 Opscode, Inc - All Rights Reserved   91
Thursday, March 17, 2011

This is on the LWRP page of the wiki.
Example resource

                    cookbooks/mysql/resources/database.rb


              actions :create_db

              attribute     :host, :kind_of => String
              attribute     :username, :kind_of => String
              attribute     :password, :kind_of => String
              attribute     :database, :kind_of => String
              attribute     :exists, :default => false




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   92
Thursday, March 17, 2011

Simple example of a resource. Sorry that they’re called attributes, not the same as node
attributes.
Lightweight Providers

   Resources need providers
   DSL defines action methods
   Chef Recipe DSL is extended
        You can use Chef resources in action methods!




                           Copyright © 2010 Opscode, Inc - All Rights Reserved   93
Thursday, March 17, 2011
Provider action code
                                                                             Good!
             action :create_db do
               unless @mysqldb.exists
                 Chef::Log.info "Creating database #{new_resource.database}"
                 execute "create #{new_resource.database}" do
                   command "mysqladmin -uroot -h localhost create #{new_resource.database}"
                 end
                 new_resource.updated_by_last_action(true)
               end
             end




    action :create_db do
                                                                            Better!
      unless @mysqldb.exists
        Chef::Log.info "Creating database #{new_resource.database}"
        db.query("create database #{new_resource.database}")
        new_resource.updated_by_last_action(true)
      end
    end

                                          Copyright © 2010 Opscode, Inc - All Rights Reserved   94
Thursday, March 17, 2011
Design Pattern 47: Use
            moar Ruby!


                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   95
Thursday, March 17, 2011

Reusing resources is cool, but sometimes its better style to use Ruby. It depends. The
advantage of reusing resources is that they’re already idempotent. Except Execute.
Make it idempotent



  def load_current_resource
    @mysqldb = Chef::Resource::MysqlDatabase.new(new_resource.name)
    @mysqldb.database(new_resource.database)
    exists = db.list_dbs.include?(new_resource.database)
    @mysqldb.exists(exists)
  end




                                    Copyright © 2010 Opscode, Inc - All Rights Reserved      96
Thursday, March 17, 2011

Its important to make providers idempotent. The load current resource is called by chef to
see what state the resource is. You have to write the code that determines the state.
Use it in a recipe!




                    mysql_database "my_app" do
                      host "localhost"
                      username "root"
                      password node['mysql']['server_root_passwd']
                      database "my_app_production"
                      action :create_db
                    end




                                       Copyright © 2010 Opscode, Inc - All Rights Reserved   97
Thursday, March 17, 2011
Metadata



                            Copyright © 2010 Opscode, Inc - All Rights Reserved   98
Thursday, March 17, 2011

A thing about metadata
Metadata
   cookbooks/gnu_parallel/metadata.rb
   maintainer              "Opscode, Inc."
   maintainer_email        "cookbooks@opscode.com"
   license                 "Apache 2.0"
   description             "Installs/Configures gnu_parallel"
   long_description        IO.read(File.join(File.dirname(__FILE__),
   'README.md'))
   version                 "0.99.0"

   depends "build-essential"




                                      Copyright © 2010 Opscode, Inc - All Rights Reserved   99
Thursday, March 17, 2011

Declare dependencies on other cookbooks with metadata.
include_recipe



                               Copyright © 2010 Opscode, Inc - All Rights Reserved   100
Thursday, March 17, 2011
libraries



                            Copyright © 2010 Opscode, Inc - All Rights Reserved   101
Thursday, March 17, 2011
LWRPs



                           Copyright © 2010 Opscode, Inc - All Rights Reserved   102
Thursday, March 17, 2011
templates



                             Copyright © 2010 Opscode, Inc - All Rights Reserved   103
Thursday, March 17, 2011
Anything from other
                    cookbooks.


                           Copyright © 2010 Opscode, Inc - All Rights Reserved   104
Thursday, March 17, 2011
Metadata not required
              for Chef Solo


                                    Copyright © 2010 Opscode, Inc - All Rights Reserved    105
Thursday, March 17, 2011

because you have to ship all the cookbooks to the node because there’s no chef server to
distribute the required cookbooks
Testing cookbooks



                                     Copyright © 2010 Opscode, Inc - All Rights Reserved   106
Thursday, March 17, 2011

Gotta test that the design was good, right?
No, not BDD/TDD



                                   http://www.flickr.com/photos/davies/4782586685
                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   107
Thursday, March 17, 2011

Though the chef source code itself has a heap of rspec/cucumber tests
Ruby




                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   http://www.flickr.com/photos/thisisbossi/3526698689/   108
Thursday, March 17, 2011

Though the code is just ruby, you could write specs and features etc, we don’t have any
examples or know of (m)any people doing this because its easy to test.
knife cookbook upload
                                     (chef-server)



                                      Copyright © 2010 Opscode, Inc - All Rights Reserved   109
Thursday, March 17, 2011

No I mean test it for reals. Upload to the Chef server.
tar -czf cookbooks.tar.gz
                                 (chef-solo)



                                Copyright © 2010 Opscode, Inc - All Rights Reserved   110
Thursday, March 17, 2011

Or create a tarball for solo.
vagrantup.com




                                  Copyright © 2010 Opscode, Inc - All Rights Reserved   111
Thursday, March 17, 2011

Anyway, you have your cookbooks somewhere the node(s) can get them. Use what you like to
test the recipes. A lot of people like Vagrant.
knife ec2 server create



                                   Copyright © 2010 Opscode, Inc - All Rights Reserved   112
Thursday, March 17, 2011

Some people like ec2. Or rackspace, whatever.
NOT




                                     Copyright © 2010 Opscode, Inc - All Rights Reserved
                                    http://www.flickr.com/photos/valeriebb/290711738         113
Thursday, March 17, 2011

Use what you like for test machines. That part isn’t important.
sudo chef-client


                           sudo chef-solo
                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   114
Thursday, March 17, 2011

Whatever, you need to run Chef to test.
Copyright © 2010 Opscode, Inc - All Rights Reserved
                           http://www.flickr.com/photos/billburris/2245430380/      115
Thursday, March 17, 2011

Show your work
git push



                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   116
Thursday, March 17, 2011

Put it on your github repository!
Copyright © 2010 Opscode, Inc - All Rights Reserved   117
Thursday, March 17, 2011
knife cookbook site share



                                    Copyright © 2010 Opscode, Inc - All Rights Reserved   118
Thursday, March 17, 2011

go that extra step and publish on the cookbooks site.

flat namespace like rubygems.org though but we’re working to change that
Copyright © 2010 Opscode, Inc - All Rights Reserved   119
Thursday, March 17, 2011

Posted it to the cookbooks site.
Opscode’s cookbook examples

   aws
   gnu_parallel
   mysql
   nagios
   radiant

                           http://ckbk.it/NAME

                               Copyright © 2010 Opscode, Inc - All Rights Reserved   120
Thursday, March 17, 2011
Thanks!

   www.opscode.com/chef
   IRC and Mailing lists
   ‣ irc.freenode.net #chef
   ‣ lists.opscode.com

   Twitter:
   ‣ @opscode, #opschef
   ‣ @jtimberman




                           Copyright © 2010 Opscode, Inc - All Rights Reserved   121
Thursday, March 17, 2011

Weitere ähnliche Inhalte

Ähnlich wie Mwrc2011 cookbook design patterns

Opscode Lightning Talk - Operations as Code
Opscode Lightning Talk - Operations as CodeOpscode Lightning Talk - Operations as Code
Opscode Lightning Talk - Operations as CodeJohn Willis
 
HTML5: Toolkits and Gaps
HTML5: Toolkits and GapsHTML5: Toolkits and Gaps
HTML5: Toolkits and Gapsdylanks
 
3. cloudcamp lt
3. cloudcamp lt3. cloudcamp lt
3. cloudcamp ltOpsCamp
 
Operations as Code
Operations as CodeOperations as Code
Operations as CodeOpsCamp
 
Dojo Mobile
Dojo MobileDojo Mobile
Dojo Mobiledylanks
 
Presentation Yoast SEO for TYPO3 and Magento
Presentation Yoast SEO for TYPO3 and MagentoPresentation Yoast SEO for TYPO3 and Magento
Presentation Yoast SEO for TYPO3 and MagentoRichard Haeser
 
Why Your API Sucks - #BAPI SF
Why Your API Sucks - #BAPI SFWhy Your API Sucks - #BAPI SF
Why Your API Sucks - #BAPI SFSeth Blank
 
Chef in the cloud [dbccg]
Chef in the cloud [dbccg]Chef in the cloud [dbccg]
Chef in the cloud [dbccg]jtimberman
 
Derailed chef update-oct2010
Derailed chef update-oct2010Derailed chef update-oct2010
Derailed chef update-oct2010jtimberman
 
Flash Platform Ovierview
Flash Platform OvierviewFlash Platform Ovierview
Flash Platform Ovierviewluca mezzalira
 
HTML XHTML HTML5
HTML XHTML HTML5HTML XHTML HTML5
HTML XHTML HTML5timstone
 
Searching does not mean finding Stuff - Apache Solr for TYPO3
Searching does not mean finding Stuff - Apache Solr for TYPO3Searching does not mean finding Stuff - Apache Solr for TYPO3
Searching does not mean finding Stuff - Apache Solr for TYPO3Olivier Dobberkau
 
Velocity2011 chef-workshop
Velocity2011 chef-workshopVelocity2011 chef-workshop
Velocity2011 chef-workshopjtimberman
 
Node js techtalksto
Node js techtalkstoNode js techtalksto
Node js techtalkstoJason Diller
 
Yoast SEO for TYPO3 and Magento 2
Yoast SEO for TYPO3 and Magento 2Yoast SEO for TYPO3 and Magento 2
Yoast SEO for TYPO3 and Magento 2Richard Haeser
 
Caelum dicas web 2010
Caelum dicas web 2010Caelum dicas web 2010
Caelum dicas web 2010Fabio Akita
 
Anemoi Solution Presentation.pdf
Anemoi Solution Presentation.pdfAnemoi Solution Presentation.pdf
Anemoi Solution Presentation.pdfssuser12a897
 

Ähnlich wie Mwrc2011 cookbook design patterns (20)

Opscode Lightning Talk - Operations as Code
Opscode Lightning Talk - Operations as CodeOpscode Lightning Talk - Operations as Code
Opscode Lightning Talk - Operations as Code
 
Operations as Code
Operations as CodeOperations as Code
Operations as Code
 
HTML5: Toolkits and Gaps
HTML5: Toolkits and GapsHTML5: Toolkits and Gaps
HTML5: Toolkits and Gaps
 
3. cloudcamp lt
3. cloudcamp lt3. cloudcamp lt
3. cloudcamp lt
 
Operations as Code
Operations as CodeOperations as Code
Operations as Code
 
Oper
OperOper
Oper
 
Dojo Mobile
Dojo MobileDojo Mobile
Dojo Mobile
 
Presentation Yoast SEO for TYPO3 and Magento
Presentation Yoast SEO for TYPO3 and MagentoPresentation Yoast SEO for TYPO3 and Magento
Presentation Yoast SEO for TYPO3 and Magento
 
Why Your API Sucks - #BAPI SF
Why Your API Sucks - #BAPI SFWhy Your API Sucks - #BAPI SF
Why Your API Sucks - #BAPI SF
 
Chef in the cloud [dbccg]
Chef in the cloud [dbccg]Chef in the cloud [dbccg]
Chef in the cloud [dbccg]
 
Derailed chef update-oct2010
Derailed chef update-oct2010Derailed chef update-oct2010
Derailed chef update-oct2010
 
Flash Platform Ovierview
Flash Platform OvierviewFlash Platform Ovierview
Flash Platform Ovierview
 
HTML XHTML HTML5
HTML XHTML HTML5HTML XHTML HTML5
HTML XHTML HTML5
 
Tim stone.html5.rjug.20110316
Tim stone.html5.rjug.20110316Tim stone.html5.rjug.20110316
Tim stone.html5.rjug.20110316
 
Searching does not mean finding Stuff - Apache Solr for TYPO3
Searching does not mean finding Stuff - Apache Solr for TYPO3Searching does not mean finding Stuff - Apache Solr for TYPO3
Searching does not mean finding Stuff - Apache Solr for TYPO3
 
Velocity2011 chef-workshop
Velocity2011 chef-workshopVelocity2011 chef-workshop
Velocity2011 chef-workshop
 
Node js techtalksto
Node js techtalkstoNode js techtalksto
Node js techtalksto
 
Yoast SEO for TYPO3 and Magento 2
Yoast SEO for TYPO3 and Magento 2Yoast SEO for TYPO3 and Magento 2
Yoast SEO for TYPO3 and Magento 2
 
Caelum dicas web 2010
Caelum dicas web 2010Caelum dicas web 2010
Caelum dicas web 2010
 
Anemoi Solution Presentation.pdf
Anemoi Solution Presentation.pdfAnemoi Solution Presentation.pdf
Anemoi Solution Presentation.pdf
 

Mwrc2011 cookbook design patterns

  • 1. Cookbook Design Patterns Speaker: Joshua Timberman Sr. Technical Evangelist ‣ joshua@opscode.com ‣ @jtimberman ‣ www.opscode.com Copyright © 2010 Opscode, Inc - All Rights Reserved 1 Thursday, March 17, 2011 Welcome
  • 2. Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/anotherphotograph/2100904507/sizes/o/ 2 Thursday, March 17, 2011
  • 3. cider:~/dev/cookbooks% git log | grep -ic "timberman" 950 Copyright © 2010 Opscode, Inc - All Rights Reserved 3 Thursday, March 17, 2011 I write cookbooks
  • 4. Copyright © 2010 Opscode, Inc - All Rights Reserved 4 Thursday, March 17, 2011 Training, services and evangelism
  • 5. Developers? Systems Administrators? Developers who do system administration? “Business” People? http://www.flickr.com/photos/timyates/2854357446/sizes/l/ Copyright © 2010 Opscode, Inc - All Rights Reserved 5 Thursday, March 17, 2011 Enough about me, who are you?
  • 6. Copyright © 2010 Opscode, Inc - All Rights Reserved 6 Thursday, March 17, 2011 Lets talk about chef
  • 7. http://www.flickr.com/photos/tambako/4444066932/ Copyright © 2010 Opscode, Inc - All Rights Reserved 7 Thursday, March 17, 2011 Show of hands time! How many people....
  • 8. ...solo? Copyright © 2010 Opscode, Inc - All Rights Reserved 8 Thursday, March 17, 2011 Who is using chef solo, Directly on your own or through a service like EY?
  • 9. ...server? Copyright © 2010 Opscode, Inc - All Rights Reserved 9 Thursday, March 17, 2011 Who’s using their own Open Source chef server?
  • 10. ...Platform? Copyright © 2010 Opscode, Inc - All Rights Reserved 10 Thursday, March 17, 2011 Who is using the Opscode Platform?
  • 11. Chef enables infrastructure as code Manage configuration as idempotent Resources. Put them together in Recipes. Track it like Source Code. Configure your servers. package "haproxy" do action :install end template "/etc/haproxy/haproxy.cfg" do source "haproxy.cfg.erb" owner "root" group "root" mode 0644 notifies :restart, "service[haproxy]" end service "haproxy" do action [:enable, :start] end Copyright © 2010 Opscode, Inc - All Rights Reserved 11 Thursday, March 17, 2011 This isn’t a talk about how Chef works or the nitty gritty, we assume that you have some familiarity with Chef already. And there’s lots of resources for learning :).
  • 12. wiki.opscode.com help.opscode.com joshua@opscode.com @jtimberman http://www.flickr.com/photos/38299630@N05/3635356091/ Copyright © 2010 Opscode, Inc - All Rights Reserved 12 Thursday, March 17, 2011 If you want to know more, find me
  • 13. Chef provides an MVC framework Copyright © 2010 Opscode, Inc - All Rights Reserved 13 Thursday, March 17, 2011 Chef is an MVC framework for building infrastructure. How is that?
  • 14. { "kernel": { "machine": "x86_64", "name": "Darwin", "os": "Darwin", "version": "Darwin Kernel Version 10.4.0: Fri Apr 23 18:28:53 PDT 2010; root:xnu-1504.7.4~1/RELEASE_I386", "release": "10.4.0" }, Node attributes are the "platform_version": "10.6.4", "platform": "mac_os_x", "platform_build": "10F569", model "domain": "local", "os": "darwin", "current_user": "jtimberman", "ohai_time": 1278602661.60043, "os_version": "10.4.0", "uptime": "18 days 17 hours 49 minutes 18 seconds", "ipaddress": "10.13.37.116", "hostname": "cider", "fqdn": "cider.local", "uptime_seconds": 1619358 } Copyright © 2010 Opscode, Inc - All Rights Reserved 14 Thursday, March 17, 2011 Models are data. Attributes are data. We’re going to process and mold the data to get to where we want to be.
  • 15. A configured node is the view Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/peterrosbjerg/3913766224/ 15 Thursday, March 17, 2011 And where we want to be is a configured node. Running a Rails app, database, middleware, whatever.
  • 16. Recipes are the controller http://www.flickr.com/photos/roadsidepictures/2478953342/sizes/o/ Copyright © 2010 Opscode, Inc - All Rights Reserved 16 Thursday, March 17, 2011 They do all the processing of the data to build the view.
  • 17. Recipes are Ruby. Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/thisisbossi/3526698689/ 17 Thursday, March 17, 2011 Since recipes are Ruby, that gives us a lot of power and flexibility.
  • 18. Cookbooks are packages of recipes http://www.flickr.com/photos/riggenransom/4140166239 Copyright © 2010 Opscode, Inc - All Rights Reserved 18 Thursday, March 17, 2011 Recipes and supporting code, assets, etc.
  • 19. Design patterns are applicable to cookbooks Copyright © 2010 Opscode, Inc - All Rights Reserved 19 Thursday, March 17, 2011 Since recipes and other things are code, and we’re really talking about infrastructure as code, there’s good design patterns!
  • 20. Cookbooks represent best practices. Copyright © 2010 Opscode, Inc - All Rights Reserved 20 Thursday, March 17, 2011
  • 21. Best practices are opinions. Copyright © 2010 Opscode, Inc - All Rights Reserved 21 Thursday, March 17, 2011
  • 22. Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/peyri/304354485 22 Thursday, March 17, 2011 So lets talk about cookbooks
  • 23. Copyright © 2010 Opscode, Inc - All Rights Reserved 23 Thursday, March 17, 2011 Of course I really mean Opscode’s cookbooks
  • 24. Copyright © 2010 Opscode, Inc - All Rights Reserved 24 Thursday, March 17, 2011 Question: fork/clone/watch? Thanks! Contributed? You’re awesome, thank you! Tried to contribute and I told you to sign a CLA? Apache license requirement
  • 25. http://www.opscode.com/blog/2009/08/11/why-we- chose-the-apache-license/ Copyright © 2010 Opscode, Inc - All Rights Reserved 25 Thursday, March 17, 2011 Please sign a CLA, its for you as much for us
  • 26. Copyright © 2010 Opscode, Inc - All Rights Reserved 26 Thursday, March 17, 2011 This is the important part: it doesn’t assign copyright to Opscode, you enable us to bundle and redistribute your work, which means your code reaches a lot of people, yay!
  • 27. Copyright © 2010 Opscode, Inc - All Rights Reserved 27 Thursday, March 17, 2011 But you can also have your code reach a lot of people through Opscode’s Chef Community site: Its like RubyGems for Chef cookbooks. You don’t need to sign a CLA. Its also easier to find cookbooks than trawling through github.
  • 28. Cookbooks package configuration README attributes/ definitions/ files/ libraries/ metadata.rb providers/ recipes/ resources/ templates/ Copyright © 2010 Opscode, Inc - All Rights Reserved 28 Thursday, March 17, 2011 Cookbooks can have a bunch of stuff in them. Lets talk about this stuff.
  • 29. Copyright © 2010 Opscode, Inc - All Rights Reserved 29 Thursday, March 17, 2011 Question: Who saw this blog post? It talks about how writing your readme first to get clarity about the code, plus it gives a nice bit of documentation.
  • 30. No really, write the fine manual. http://www.flickr.com/photos/bike/2263136517 Copyright © 2010 Opscode, Inc - All Rights Reserved 30 Thursday, March 17, 2011
  • 31. Writing Recipes Copyright © 2010 Opscode, Inc - All Rights Reserved 31 Thursday, March 17, 2011 Okay, you got writing the README out of the way, or maybe you didn’t. Now write the recipes.
  • 32. Contrived Example Copyright © 2010 Opscode, Inc - All Rights Reserved 32 Thursday, March 17, 2011 A real world example
  • 33. Copyright © 2010 Opscode, Inc - All Rights Reserved 33 Thursday, March 17, 2011 So I was at FOSDEM this year. Did anyone go? Fosdem is a huge free conference in Europe, 5000+ people, 300 talks, 2 days.
  • 34. GNU parallel http://www.gnu.org/software/parallel/ It replaces xargs Copyright © 2010 Opscode, Inc - All Rights Reserved 34 Thursday, March 17, 2011 One of the 300 talks was on GNU parallel.
  • 35. I wrote a cookbook during the talk. http://www.flickr.com/photos/jenorton/2229437427/ Copyright © 2010 Opscode, Inc - All Rights Reserved 35 Thursday, March 17, 2011
  • 36. This isn’t because I’m awesome. Copyright © 2010 Opscode, Inc - All Rights Reserved 36 Thursday, March 17, 2011
  • 37. Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/flikr/131433774/ 37 Thursday, March 17, 2011 Cats with laser eyes are awesome.
  • 38. Nor because the talk was boring. Copyright © 2010 Opscode, Inc - All Rights Reserved 38 Thursday, March 17, 2011
  • 39. I wanted to write one anyway. Copyright © 2010 Opscode, Inc - All Rights Reserved 39 Thursday, March 17, 2011
  • 40. GNU Parallel is like almost any GNU software. wget ftp://ftp.gnu.org/gnu/thing/thing.tar.gz tar -zxvf thing.tar.gz cd thing ./configure && make && make install Rejoice! Copyright © 2010 Opscode, Inc - All Rights Reserved 40 Thursday, March 17, 2011
  • 41. Do that in a recipe remote_file "/tmp/parallel-20110205.tar.bz2" do source "http://ftp.gnu.org/gnu/parallel/parallel-20110205.tar.bz2" end bash "build gnu parallel from source" do cwd "/tmp" code <<-EOF tar -jxvf parallel-20110205.tar.bz2 (cd parallel-20110205 && ./configure) (cd parallel-20110205 && make && make install) EOF end Copyright © 2010 Opscode, Inc - All Rights Reserved 41 Thursday, March 17, 2011 So do that in a recipe.
  • 42. That wasn’t hard. Copyright © 2010 Opscode, Inc - All Rights Reserved 42 Thursday, March 17, 2011 Big deal, thats not hard. I can do that in about 42 seconds. And I did.
  • 43. But thats a horrible recipe. Copyright © 2010 Opscode, Inc - All Rights Reserved 43 Thursday, March 17, 2011 Not because it installs from source. Unless..
  • 44. '-. .-' _______________'-._________.-'______________ '-. _ '-. .-' _ .-' '-. (_) / (_) .-' '-. / .-' '-.____/ ____.-' _ _ _ _ _ / ////////// /////////// |||| .-----------._|||| |||| '-|___|___|-' |||| '---------' //// |||||||||||||/// /////// ///// jnh http://triple-double-u.com/ascii/?s=ascii-art&y=weather&q=ab/beard.txt http://ascii-art.de/info/copyright/ Copyright © 2010 Opscode, Inc - All Rights Reserved 44 Thursday, March 17, 2011 Unless you have a unix sysadmin beard :) and package everything.
  • 45. Really, why is it bad? Copyright © 2010 Opscode, Inc - All Rights Reserved 45 Thursday, March 17, 2011
  • 46. remote_file problems Can’t download from a different location! Can’t download a different version! The file gets downloaded every time to verify the checksum. Use customizable attributes remote_file "/tmp/parallel-20110205.tar.bz2" do source "http://ftp.gnu.org/gnu/parallel/parallel-20110205.tar.bz2" end Copyright © 2010 Opscode, Inc - All Rights Reserved 46 Thursday, March 17, 2011 This resource doesn’t have an easy way for someone to customize the location, or the version, and the file has to be downloaded in order to verify the checksum every time.
  • 47. Design Pattern 1: Attributes Copyright © 2010 Opscode, Inc - All Rights Reserved 47 Thursday, March 17, 2011 So we reach our first design pattern, use attributes.
  • 48. In cookbooks/gnu_parallel/attributes/default.rb: default['gnu_parallel']['url'] = 'http://ftp.gnu.org/gnu/parallel' default['gnu_parallel']['version'] = '20110205' default['gnu_parallel']['checksum'] = 'sha256s dont fit on slides' Copyright © 2010 Opscode, Inc - All Rights Reserved 48 Thursday, March 17, 2011 Wait, but I know what versions, and urls and everything in my infrastructure. Yeah but if you want to share that, random folks on the internet don’t have the same infrastructure.
  • 49. /tmp isn’t a great location Some systems clear it on reboot. This causes the file to be downloaded again. Use Chef::Config[:file_cache_path]. Copyright © 2010 Opscode, Inc - All Rights Reserved 49 Thursday, March 17, 2011 Downloading to /tmp isn’t a great solution either.
  • 50. Design Pattern 2: Exploit Chef internal values Copyright © 2010 Opscode, Inc - All Rights Reserved 50 Thursday, March 17, 2011 Second pattern, leverage the ability to access Chef’s Ruby objects in Recipes.
  • 51. remote_file using attributes version = node['gnu_parallel']['version'] cache_path = Chef::Config[:file_cache_path] remote_file "#{cache_path}/parallel-#{version}.tar.bz2" do source "#{node['gnu_parallel']['url']}/parallel-#{version}.tar.bz2" checksum node['gnu_parallel']['checksum'] mode 0644 end Copyright © 2010 Opscode, Inc - All Rights Reserved 51 Thursday, March 17, 2011 So now we have a remote file resource that uses some attributes, and internal Chef values.
  • 52. bash script problems bash "build gnu parallel from source" do cwd "/tmp" code <<-EOF tar -jxvf parallel-20110205.tar.bz2 (cd parallel-20110205 && ./configure) (cd parallel-20110205 && make && make install) EOF end Least of all is compiling from source :-) Copyright © 2010 Opscode, Inc - All Rights Reserved 52 Thursday, March 17, 2011 The other resource in the recipe has problems.
  • 53. bash script solutions! The version needs to be an attribute. The default configure options may not be useful. Moar attributes. default['gnu_parallel']['configure_options'] = [] Copyright © 2010 Opscode, Inc - All Rights Reserved 53 Thursday, March 17, 2011 We should reuse the version attribute, which we saw earlier. What if we want to customize how things are compiled, or the install prefix? Define that as an attribute and set it to an empty array, user can modify the attribute in a role or on the node.
  • 54. Design Pattern 3: Sane defaults easily changed Copyright © 2010 Opscode, Inc - All Rights Reserved 54 Thursday, March 17, 2011 Empty configure options is sane because there aren’t any of those enabled when you do a normal ./configure when compiling from source.
  • 55. bash script using attributes config_opts = node['gnu_parallel']['configure_options'].join(" ") bash "build gnu parallel" do cwd Chef::Config[:file_cache_path] code <<-EOF tar -jxvf parallel-#{version}.tar.bz2 (cd parallel-#{version} && ./configure #{config_opts}) (cd parallel-#{version} && make && make install) EOF end Copyright © 2010 Opscode, Inc - All Rights Reserved 55 Thursday, March 17, 2011 So here we add a little more ruby, but gain a lot more flexibility. We’re Rubyists, so we’re not scared of Ruby.
  • 56. '-. .-' _______________'-._________.-'______________ '-. _ '-. .-' _ .-' '-. (_) / (_) .-' '-. / .-' '-.____/ ____.-' _ _ _ _ _ / ////////// /////////// |||| .-----------._|||| |||| '-|___|___|-' |||| '---------' //// |||||||||||||/// /////// ///// jnh http://triple-double-u.com/ascii/?s=ascii-art&y=weather&q=ab/beard.txt http://ascii-art.de/info/copyright/ Copyright © 2010 Opscode, Inc - All Rights Reserved 56 Thursday, March 17, 2011 The README tells his guy how to modify the attributes to customize how to configure and where to install. ... Of course he’s going to make a package anyway.
  • 57. Attribute conditional on platform in attributes file case node['platform'] when "centos" default['gnu_parallel']['install_method'] = 'package' else default['gnu_parallel']['install_method'] = 'source' end cookbooks/gnu_parallel/default.rb include_recipe "gnu_parallel::#{node['gnu_parallel']['install_method']}" cookbooks/gnu_parallel/package.rb package "gnu-parallel" Copyright © 2010 Opscode, Inc - All Rights Reserved 57 Thursday, March 17, 2011 Select which recipe to use based on platform, on centos we’ll install from package using the package recipe
  • 58. Design Pattern 12: Platform specific conditionals Copyright © 2010 Opscode, Inc - All Rights Reserved 58 Thursday, March 17, 2011 Its good to utilize chef’s ability to look up the node’s platform and select behavior or set attributes based on the platform.
  • 59. INFO: remote_file[/var/cache/chef/parallel-20110205.tar.bz2]: Creating /var/cache/chef/parallel-20110205.tar.bz2 INFO: Setting mode to 644 for remote_file[/var/cache/chef/ parallel-20110205.tar.bz2] INFO: Ran bash[build gnu parallel] successfully Copyright © 2010 Opscode, Inc - All Rights Reserved 59 Thursday, March 17, 2011 All that said, we can run chef on the node and get the source installed gnu-parallel, and share this cookbook with other users who can use it how they wish. Yay!
  • 60. All that in ~30 minutes Copyright © 2010 Opscode, Inc - All Rights Reserved 60 Thursday, March 17, 2011
  • 61. Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/flikr/131433774/ 61 Thursday, March 17, 2011 Because I really am a Cat with Laser Eyes!
  • 62. Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/rutty/438775617 62 Thursday, March 17, 2011 Here’s a giant rubber duck. Quack.
  • 63. Recipes Copyright © 2010 Opscode, Inc - All Rights Reserved 63 Thursday, March 17, 2011 Lets talk about Recipes a bit more. We saw a contrived example recipe, lets look at how to best to utilize recipes in cookbooks. These are where we formulate our opinions.
  • 64. Recipes Separate by functionality default client server ... etc Copyright © 2010 Opscode, Inc - All Rights Reserved 64 Thursday, March 17, 2011 It is totally okay to have separate recipes split up by functionality of what they’re configuring. We saw some of this with the package vs source recipes earlier.
  • 65. Recipes Avoid hardcoding data node attributes data bags chef search Copyright © 2010 Opscode, Inc - All Rights Reserved 65 Thursday, March 17, 2011 Chef has a rich set of features that allow us to avoid hardcoding data in recipes In addition to attributes that we saw earlier, when using the Chef Server we can use data bags and search.
  • 66. Code Reuse! http://www.flickr.com/photos/dnorman/3314634378 Copyright © 2010 Opscode, Inc - All Rights Reserved 66 Thursday, March 17, 2011 Reduce, reuse, recycle.
  • 67. Design Pattern 4: Separate recipes Copyright © 2010 Opscode, Inc - All Rights Reserved 67 Thursday, March 17, 2011
  • 68. Separate by functionality default.rb client.rb server.rb Copyright © 2010 Opscode, Inc - All Rights Reserved 68 Thursday, March 17, 2011 default - install common components, should do what one might expect client - set up to talk to a server, use search to find the server based on a role server - set up the server part, search to find clients
  • 69. Our Nagios cookbook uses this pattern. http://www.flickr.com/photos/cote/163746456 Copyright © 2010 Opscode, Inc - All Rights Reserved 69 Thursday, March 17, 2011
  • 70. %w{ nagios-nrpe-server nagios-plugins nagios-plugins-basic nagios-plugins-standard }.each do |pkg| package pkg end remote_directory "/usr/lib/nagios/plugins" do source "plugins" owner "nagios" group "nagios" mode 0755 files_mode 0755 end Copyright © 2010 Opscode, Inc - All Rights Reserved 70 Thursday, March 17, 2011 nagios::default, packages and plugins.
  • 71. Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/zigazou76/3702501888 71 Thursday, March 17, 2011 Danger! We’re going to talk about some Chef Server features.
  • 72. search(:node, "role:#{node[:nagios][:server_role]}") do |n| mon_host << n['ipaddress'] end package "nagios-nrpe-server" template "/etc/nagios/nrpe.cfg" do source "nrpe.cfg.erb" owner "nagios" group "nagios" mode "0644" variables :mon_host => mon_host notifies :restart, "service[nagios-nrpe-server]" end service "nagios-nrpe-server" do action [:enable,:start] end Copyright © 2010 Opscode, Inc - All Rights Reserved 72 Thursday, March 17, 2011 nagios::client is a bit more interesting, where we search for the system that is the monitoring server and then allow it to connect.
  • 73. include_recipe "nagios::client" nodes = search(:node, "hostname:*") package "nagios3" template "/etc/nagios3/hosts.cfg" do source "hosts.cfg.erb" owner "nagios" group "nagios" mode 0644 variables :nodes => nodes notifies :restart, "service[nagios3]" end service "nagios3" do action [ :enable, :start] end Copyright © 2010 Opscode, Inc - All Rights Reserved 73 Thursday, March 17, 2011 Similiarly in nagios::server we search for all the nodes to monitor.
  • 74. But I use Chef Solo. Copyright © 2010 Opscode, Inc - All Rights Reserved 74 Thursday, March 17, 2011 So all thats wonderful if you’re using a Server. But you’re not. You’re using Solo.
  • 75. Benefits of Chef Server Persistent node data Arbitrary infrastructure data Search indexes API Copyright © 2010 Opscode, Inc - All Rights Reserved 75 Thursday, March 17, 2011 A sidebar about solo vs server flexibility and reuse you might be missing.
  • 76. Design Pattern 6L: Check for Chef Solo. Copyright © 2010 Opscode, Inc - All Rights Reserved 76 Thursday, March 17, 2011
  • 77. if Chef::Config[:solo] node_list = nodes['mything']['node_list'] else node_list = search(:node, "role:mything") end Copyright © 2010 Opscode, Inc - All Rights Reserved 77 Thursday, March 17, 2011 Make a conditional check for solo before doing something like a search, or loading from a data bag or other server-only feature.
  • 78. Hardcoding data: Anti-pattern Customizable cookbooks Document default attributes README! Let users override with roles Abstract to data bags non-role/non-node specific like application info Play nice with chef-solo Copyright © 2010 Opscode, Inc - All Rights Reserved 78 Thursday, March 17, 2011 Hardcoding recipes is an anti pattern. We already saw this.
  • 79. Templates and Files Copyright © 2010 Opscode, Inc - All Rights Reserved 79 Thursday, March 17, 2011 Lets talk about some of the good things you can do with cookbook assets - templates and files
  • 80. File specificity cookbooks/mysql/templates centos/ debian/ default/ redhat/ ubuntu-10.04/ ubuntu-8.04/ ubuntu-9.10/ all contain my.cnf.erb rendered template picked based on node’s platform Copyright © 2010 Opscode, Inc - All Rights Reserved 80 Thursday, March 17, 2011 File specificity is useful if your environment has multiple platforms, or if you’re using cookbooks from others that support platforms different than your own. Generally, install the package, grab the default config file and stick it in the right directory.
  • 81. Static vs Dynamic Resources cookbook_file is static template is dynamic Duh :). Copyright © 2010 Opscode, Inc - All Rights Reserved 81 Thursday, March 17, 2011 In recipes, use the appropriate resources.
  • 82. You want dynamic Easily sharable Data driven Rich data from multiple sources Copyright © 2010 Opscode, Inc - All Rights Reserved 82 Thursday, March 17, 2011 So you want templates. Use them. They’re ERB, so <3 for Rubyists. And they help others customize your cookbook for their environment with attributes, of course
  • 83. Libraries, Definitions, Resources and Providers Copyright © 2010 Opscode, Inc - All Rights Reserved 83 Thursday, March 17, 2011 Cookbooks are more than just recipes and assets (and attributes). Lets talk about libraries, definitions, resources and providers.
  • 84. Libraries Recipe helpers LWRP helpers Heavyweight R/P Copyright © 2010 Opscode, Inc - All Rights Reserved 84 Thursday, March 17, 2011 Extend chef with libraries, like enhance recipes with helpers.
  • 85. Recipe Helpers Use Chef::Recipe class Methods are available directly in recipes # in the library class Chef class Recipe def radiant_edge? node[:radiant][:edge] end end end # in the recipe if radiant_edge? deploy "/srv/radiant" do repository "git://github.com/radiant/radiant.git" end end Copyright © 2010 Opscode, Inc - All Rights Reserved 85 Thursday, March 17, 2011 Extend the Chef::Recipe class.
  • 86. LWRP Helpers Don’t repeat yourself! Abstract API calls module Opscode module Aws module Ec2 def ec2 @@ec2 ||= RightAws::Ec2.new( new_resource.aws_access_key, new_resource.aws_secret_access_key, { :logger => Chef::Log } ) end end end end # in provider: include Opscode::Aws::Ec2 ... ec2.describe_addresses.find{|a| a[:public_ip] == ip} ... Copyright © 2010 Opscode, Inc - All Rights Reserved 86 Thursday, March 17, 2011 in our aws cookbook
  • 87. Heavyweight Resources & Providers Full Ruby classes like those in Chef itself Allow behaviors not available in LWRPs ‣ inherit/extend existing resources/provider Distribute as gems ‣ chef-deploy Copyright © 2010 Opscode, Inc - All Rights Reserved 87 Thursday, March 17, 2011 Sometimes you might want to write full resources and provides.
  • 88. Definitions http://www.flickr.com/photos/thestorylady/4326274437 Copyright © 2010 Opscode, Inc - All Rights Reserved 88 Thursday, March 17, 2011 Don’t use definitions anymore. They look like resources, but they’re actually replaced by the resources they contain and they don’t send/receive notifications. Instead for more awesome, use...
  • 89. Lightweight Resources & Providers http://www.flickr.com/photos/lucynieto/2769594798 Copyright © 2010 Opscode, Inc - All Rights Reserved 89 Thursday, March 17, 2011 Aka LWRPs, these are a lightweight DSL for creating new resources and providers in your cookbooks.
  • 90. Resource DSL actions attributes validation parameters Copyright © 2010 Opscode, Inc - All Rights Reserved 90 Thursday, March 17, 2011 Resources really just contain two things, actions and attributes.
  • 91. Validation Parameters http://bit.ly/cheflwrp Option Meaning :default Default value :kind_of Value must be a kind_of?(Klass) :required Raise exception if this is missing :regex Match the value with regular expression :equal_to Value must match. :name_attribute Set to the name of the resource. :callbacks Hash of Procs, should return true. :respond_to Ensure the value has the given method. Copyright © 2010 Opscode, Inc - All Rights Reserved 91 Thursday, March 17, 2011 This is on the LWRP page of the wiki.
  • 92. Example resource cookbooks/mysql/resources/database.rb actions :create_db attribute :host, :kind_of => String attribute :username, :kind_of => String attribute :password, :kind_of => String attribute :database, :kind_of => String attribute :exists, :default => false Copyright © 2010 Opscode, Inc - All Rights Reserved 92 Thursday, March 17, 2011 Simple example of a resource. Sorry that they’re called attributes, not the same as node attributes.
  • 93. Lightweight Providers Resources need providers DSL defines action methods Chef Recipe DSL is extended You can use Chef resources in action methods! Copyright © 2010 Opscode, Inc - All Rights Reserved 93 Thursday, March 17, 2011
  • 94. Provider action code Good! action :create_db do unless @mysqldb.exists Chef::Log.info "Creating database #{new_resource.database}" execute "create #{new_resource.database}" do command "mysqladmin -uroot -h localhost create #{new_resource.database}" end new_resource.updated_by_last_action(true) end end action :create_db do Better! unless @mysqldb.exists Chef::Log.info "Creating database #{new_resource.database}" db.query("create database #{new_resource.database}") new_resource.updated_by_last_action(true) end end Copyright © 2010 Opscode, Inc - All Rights Reserved 94 Thursday, March 17, 2011
  • 95. Design Pattern 47: Use moar Ruby! Copyright © 2010 Opscode, Inc - All Rights Reserved 95 Thursday, March 17, 2011 Reusing resources is cool, but sometimes its better style to use Ruby. It depends. The advantage of reusing resources is that they’re already idempotent. Except Execute.
  • 96. Make it idempotent def load_current_resource @mysqldb = Chef::Resource::MysqlDatabase.new(new_resource.name) @mysqldb.database(new_resource.database) exists = db.list_dbs.include?(new_resource.database) @mysqldb.exists(exists) end Copyright © 2010 Opscode, Inc - All Rights Reserved 96 Thursday, March 17, 2011 Its important to make providers idempotent. The load current resource is called by chef to see what state the resource is. You have to write the code that determines the state.
  • 97. Use it in a recipe! mysql_database "my_app" do host "localhost" username "root" password node['mysql']['server_root_passwd'] database "my_app_production" action :create_db end Copyright © 2010 Opscode, Inc - All Rights Reserved 97 Thursday, March 17, 2011
  • 98. Metadata Copyright © 2010 Opscode, Inc - All Rights Reserved 98 Thursday, March 17, 2011 A thing about metadata
  • 99. Metadata cookbooks/gnu_parallel/metadata.rb maintainer "Opscode, Inc." maintainer_email "cookbooks@opscode.com" license "Apache 2.0" description "Installs/Configures gnu_parallel" long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version "0.99.0" depends "build-essential" Copyright © 2010 Opscode, Inc - All Rights Reserved 99 Thursday, March 17, 2011 Declare dependencies on other cookbooks with metadata.
  • 100. include_recipe Copyright © 2010 Opscode, Inc - All Rights Reserved 100 Thursday, March 17, 2011
  • 101. libraries Copyright © 2010 Opscode, Inc - All Rights Reserved 101 Thursday, March 17, 2011
  • 102. LWRPs Copyright © 2010 Opscode, Inc - All Rights Reserved 102 Thursday, March 17, 2011
  • 103. templates Copyright © 2010 Opscode, Inc - All Rights Reserved 103 Thursday, March 17, 2011
  • 104. Anything from other cookbooks. Copyright © 2010 Opscode, Inc - All Rights Reserved 104 Thursday, March 17, 2011
  • 105. Metadata not required for Chef Solo Copyright © 2010 Opscode, Inc - All Rights Reserved 105 Thursday, March 17, 2011 because you have to ship all the cookbooks to the node because there’s no chef server to distribute the required cookbooks
  • 106. Testing cookbooks Copyright © 2010 Opscode, Inc - All Rights Reserved 106 Thursday, March 17, 2011 Gotta test that the design was good, right?
  • 107. No, not BDD/TDD http://www.flickr.com/photos/davies/4782586685 Copyright © 2010 Opscode, Inc - All Rights Reserved 107 Thursday, March 17, 2011 Though the chef source code itself has a heap of rspec/cucumber tests
  • 108. Ruby Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/thisisbossi/3526698689/ 108 Thursday, March 17, 2011 Though the code is just ruby, you could write specs and features etc, we don’t have any examples or know of (m)any people doing this because its easy to test.
  • 109. knife cookbook upload (chef-server) Copyright © 2010 Opscode, Inc - All Rights Reserved 109 Thursday, March 17, 2011 No I mean test it for reals. Upload to the Chef server.
  • 110. tar -czf cookbooks.tar.gz (chef-solo) Copyright © 2010 Opscode, Inc - All Rights Reserved 110 Thursday, March 17, 2011 Or create a tarball for solo.
  • 111. vagrantup.com Copyright © 2010 Opscode, Inc - All Rights Reserved 111 Thursday, March 17, 2011 Anyway, you have your cookbooks somewhere the node(s) can get them. Use what you like to test the recipes. A lot of people like Vagrant.
  • 112. knife ec2 server create Copyright © 2010 Opscode, Inc - All Rights Reserved 112 Thursday, March 17, 2011 Some people like ec2. Or rackspace, whatever.
  • 113. NOT Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/valeriebb/290711738 113 Thursday, March 17, 2011 Use what you like for test machines. That part isn’t important.
  • 114. sudo chef-client sudo chef-solo Copyright © 2010 Opscode, Inc - All Rights Reserved 114 Thursday, March 17, 2011 Whatever, you need to run Chef to test.
  • 115. Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/billburris/2245430380/ 115 Thursday, March 17, 2011 Show your work
  • 116. git push Copyright © 2010 Opscode, Inc - All Rights Reserved 116 Thursday, March 17, 2011 Put it on your github repository!
  • 117. Copyright © 2010 Opscode, Inc - All Rights Reserved 117 Thursday, March 17, 2011
  • 118. knife cookbook site share Copyright © 2010 Opscode, Inc - All Rights Reserved 118 Thursday, March 17, 2011 go that extra step and publish on the cookbooks site. flat namespace like rubygems.org though but we’re working to change that
  • 119. Copyright © 2010 Opscode, Inc - All Rights Reserved 119 Thursday, March 17, 2011 Posted it to the cookbooks site.
  • 120. Opscode’s cookbook examples aws gnu_parallel mysql nagios radiant http://ckbk.it/NAME Copyright © 2010 Opscode, Inc - All Rights Reserved 120 Thursday, March 17, 2011
  • 121. Thanks! www.opscode.com/chef IRC and Mailing lists ‣ irc.freenode.net #chef ‣ lists.opscode.com Twitter: ‣ @opscode, #opschef ‣ @jtimberman Copyright © 2010 Opscode, Inc - All Rights Reserved 121 Thursday, March 17, 2011