Chef - Chef-Shell


Writing Chef cookbooks is always hard. It makes it even harder because of long feedback cycle of uploading them to the Chef server, provisioning a vagrant VM, checking how they failed there, rinsing and repeating. It would be easier if we could try to test some pieces or recipes before we do all this heavy lifting at once.

Chef comes with Chef-Shell, which is essentially an interactive Ruby session with Chef. In the Chef-Shell, we can create −

  • Attributes
  • Write Recipes
  • Initializing Chef runs

It is used to evaluate parts of recipes on the fly, before uploading them to Chef server and execute complete cookbooks on the node.

Running Shell

Step 1 − Run Chef-Shell in a standalone mode.

mma@laptop:~/chef-repo $ chef-shell 
loading configuration: none (standalone chef-shell session) 
Session type: standalone 
Loading...[2017-01-12T20:48:01+01:00] INFO: Run List is [] 
[2017-01-12T20:48:01+01:00] INFO: Run List expands to [] 
This is chef-shell, the Chef Shell. 
Chef Version: 11.0.0 
run `help' for help, `exit' or ^D to quit. 
Ohai2u mma@laptop!  
chef > 

Step 2 − Switch to attribute mode in the Chef-Shell

  • chef > attributes_mode

Step 3 − Setting attribute value.

  • chef:attributes > set[:title] = "Chef Cookbook"

    • "Chef Cookbook"

  • chef:attributes > quit

    • :attributes

  • chef >

Step 4 − Switch to recipe mode.

  • chef > recipe_mode

Step 5 − Create a file resource.

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 > 

Step 6 − Commence Chef run to create the file with the given content.

  • chef:recipe > run_chef

[2017-01-12T21:07:49+01:00] INFO: Processing file[/tmp/book.txt] 
action create ((irb#1) line 1) 
--- /var/folders/1r/_35fx24d0y5g08qs131c33nw0000gn/T/cheftempfile20121212- 
11348-dwp1zs 2012-12-12 21:07:49.000000000 
+++ /var/folders/1r/_35fx24d0y5g08qs131c33nw0000gn/T/chefdiff20121212- 
11348-hdzcp1 2012-12-12 21:07:49.000000000 +0100 
@@ -0,0 +1 @@ 
+Chef Cookbook 
\ No newline at end of file 
[2017-01-12T21:07:49+01:00] INFO: entered create 
[2017-01-12T21:07:49+01:00] INFO: file[/tmp/book.txt] created file 

How it Works

  • Chef-Shell starts with an Interactive Ruby (IRB) session enhanced with some specific features.

  • It offers modes such as attributes_mode and interactive_mode.

  • It helps in writing commands, which are written inside a recipe or cookbook.

  • It runs everything in an interactive mode.

We can run Chef-Shell in three different modes: Standalone mode, Client mode, and Solo mode.

  • Standalone mode − It is the default mode. No cookbooks are loaded, and the run-list is empty.

  • Client mode − Here, the chef-shell acts as a chef-client.

  • Solo mode − Here, the chef-shell acts as a chef-solo client.