Book Image

Chef Infrastructure Automation Cookbook Second Edition

By : Matthias Marschall
Book Image

Chef Infrastructure Automation Cookbook Second Edition

By: Matthias Marschall

Overview of this book

Table of Contents (14 chapters)
Chef Infrastructure Automation Cookbook Second Edition
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Using chef-shell


Writing cookbooks is hard. Being able to try out parts of a recipe interactively and using breakpoints really helps to understand how your recipes work.

Chef comes with chef-shell, which is essentially an interactive Ruby session with Chef. In chef-shell, you can create attributes, write recipes, and initialize Chef runs, among other things. Chef-shell allows you to evaluate parts of your recipes on the fly before uploading them to your Chef server and executeing complete cookbooks on your nodes.

How to do it...

Running chef-shell is straightforward.

  1. Start chef-shell in standalone mode:

    mma@laptop:~/chef-repo $ chef-shell
    loading configuration: none (standalone chef-shell session)
    Session type: standalone
    Loading......done.
    
    
    This is the chef-shell.
     Chef Version: 11.18.0
     http://www.chef.io/chef
     http://docs.chef.io/
    
    run `help' for help, `exit' or ^D to quit.
    
    Ohai2u mma@laptop!
    chef >
    
  2. Switch to the attributes mode in chef-shell:

    chef > attributes_mode
    
  3. Set an attribute value to be used inside the recipe later:

    chef:attributes > set[:title] = "Chef Cookbook"
     => "Chef Cookbook"
    chef:attributes > quit
     => :attributes
    chef >
    
  4. Switch to the recipe mode:

    chef > recipe_mode
    
  5. Create a file resource inside a recipe, using the title attribute as content:

    chef:recipe > file "/tmp/book.txt" do
    chef:recipe >     content node.title
    chef:recipe ?> end
     => <file[/tmp/book.txt] @name: "/tmp/book.txt" @noop: nil @before: nil @params: {} @provider: Chef::Provider::File @allowed_actions: [:nothing, :create, :delete, :touch, :create_if_missing] @action: "create" @updated: false @updated_by_last_action: false @supports: {} @ignore_failure: false @retries: 0 @retry_delay: 2 @source_line: "(irb#1):1:in `irb_binding'" @elapsed_time: 0 @resource_name: :file @path: "/tmp/book.txt" @backup: 5 @diff: nil @cookbook_name: nil @recipe_name: nil @content: "Chef Cookbook">
    chef:recipe >
    
  6. Initiate a Chef run to create the file with the given content:

    chef:recipe > run_chef
    
    [2014-12-12T22:26:42+01:00] INFO: Processing file[/tmp/book.txt] action create ((irb#1) line 1)
    ...TRUNCATED OUTPUT...
    => true

How it works...

Chef-shell starts an interactive Ruby Shell (IRB) session, which is enhanced with some Chef-specific features. It offers certain modes, such as attributes_mode or recipe_mode, which enable you to write commands like you would put them into attributes file or recipes.

Entering a resource command into the recipe context will create the given resource, but not run it yet. It's like Chef reading your recipe files and creating the resources but not yet running them. You can run all the resources you created within the recipe context using the run_chef command. This will execute all the resources on your local box and physically change your system. To play around with temporary files, your local box might do, but if you're going to do more invasive stuff, such as installing or removing packages, installing services, and so on, you might want to use chef-shell from within a Vagrant VM.

There's more...

Not only can you run chef-shell in standalone mode but you can also in Chef client mode. If you run it in Chef client mode, it will load the complete run list of your node and you'll be able to tweak it inside the chef-shell. You start the Chef client mode by using the run it --client parameter:

mma@laptop:~/chef-repo $ chef-shell --client

You can configure which Chef server to connect it to in a file called chef-shell.rb, in the same way as you do in the client.rb file on your local workstation.

You can use chef-shell to manage your Chef server, for example, listing all nodes:

chef > nodes.list
[node[my_server]]

You can put breakpoints into your recipes. If it hits a breakpoint resource, chef-shell will stop the execution of the recipe and you'll be able to inspect the current state of your Chef run:

breakpoint "name" do
  action :break
end

See also