Chef - Plain Ruby with Chef DSL


In Chef, if one needs to create simple recipes one can use resources available in Chef, such as templates, remote_file, and services. However as the recipes become elaborate, one needs advanced techniques, such as conditional statements to execute parts of the recipe on condition. This is the power of mixing plain Ruby with Chef Domain Specific Language (DSL).

How to Use It?

Start Chef Shell on any of the node in the client mode to be able to access the Chef server.

user@server:~$ sudo chef-shell --client 
loading configuration: /etc/chef/client.rb 
Session type: client 
run `help' for help, `exit' or ^D to quit. 
Ohai2u user@server! 

Basic Conditions with Chef DSL

Sort nodes by name using plain Ruby.

chef > nodes.sort! {|a,b| <=> } 
=> [node[alice],node[server]] 

Loop through the nodes, printing their operating system.

chef > nodes.each do |n| 
   chef > puts n['os'] 
   chef ?> 
=> [node[server], node[alice]] 

Install multiple Ruby gems using an array, a loop, and string expansion to construct the gem names.

chef > %w{ec2 essentials}.each do |gem| 
   chef > gem_package "knife-#{gem}" 
   chef ?> end   => ["ec2", "essentials"] 

Working Method

Chef recipes are Ruby files, which gets evaluated in the context of Chef run. They can contain plain Ruby code such as if statement and loops as well as Chef DSL elements such as resources.

Inside the recipe, one can simply declare Ruby variables and assign values to it.