Main menu

chef tutorial for beginners

Chef is a configuration management system which transforms complex infrastructure into code. Chef automates how applications are deployed, configured and manage from a single location. At first look it feels like a jargon of words but as you go deep inside it, it will solve many complex problem of you infrastructure.
Chef infrastructure devided into three main pieces

  • Chef server: Centralized repository of configuration
  • Chef client: Also known as chef nodes in which they pull the information from chef server
  • Chef workstation: Where you develop your configuration, it may be your running system you are working on.

For understanding you create configuration or recipe in term of Chief in your workstation and push it to your chef server. You configure your chef clients to pull configuration from your chef server.

Chef Basics


Here in this tutorial we are not using any of them and just try to understand the basic structure of Chef in a single machine.

Download and install chef DK

Chef DK is an development tool created by the community also include chef client into it.
Download chef DK from here for your Distribution, i am using CentOS for the article

# rpm -ivh chefdk-0.14.25-1.el7.x86_64_2.rpm

It will install all necessary packages into /opt/chefdk so not conflicts with your system libraries and configuration.

Working with chef cookbooks

Chef cookbook: It is a fundamental unit which describe infrastructure like resources, templates and attributes etc. If you not understand let’s start with it and create our first cookbook

# knife cookbook create MyFirstCookBook
 WARNING: No knife configuration file found
 ** Creating cookbook MyFirstCookBook in /var/chef/cookbooks
 ** Creating README for cookbook: MyFirstCookBook
 ** Creating CHANGELOG for cookbook: MyFirstCookBook
 ** Creating metadata for cookbook: MyFirstCookBook

knife is a command-line tool that provides an interface between a local chef-repo and the Chef serve. With knife command we can manage nodes, cookbooks and recipes, environments etc.

Let’s see the directory structure of your first cookbook. It consist of various directory and files including defaults.
Note: default is a directory or file which is used if none is specified inside your recipe or roles.

├── attributes
├── definitions
├── files
│   └── default
├── libraries
├── metadata.rb
├── providers
├── recipes
│   └── default.rb
├── resources
└── templates
└── default

 Cookbook recipe: It’s an fundamental unit of cookbook define how system should be configured and managed. i.e installing and configuration a web server.
Let’s start creating our first recipe, open recipe/default.rb in editor and insert this code

directory '/zolan' do
user 'root'
group 'root'
mode '0777'

Chef built on the top of ruby, so it’s syntax pretty much simile to it. In this recipe we have checked if /zolan directory exist, if not it will create it and apply the necessary roles and permissions. Let’s run our first cookbook

# chef-client --local-mode -o 'recipe[MyFirstCookBook]'
 Recipe: MyFirstCookBook::default
 * directory[/zolan] action create
 - create new directory /zolan
 - change mode from '' to '0777'
 - change owner from '' to 'root'
 - change group from '' to 'root'
 - restore selinux security context

chef-client –local-mode allow us to run chef-client against the local repo on the local machine instead of chef server. It has been introduce in Chef 11.8. If you using prior version of it consider using chef-solo having the same functionality.

We have only specified the cookbook name not the recipe as we modified the default recipe file.
Congratulation you have successfully crated and run your first cookbook and recipe. Now let’s try some more example with different resources

file resource: Below snippet will crate and insert the content on /zolan/index.html.

file '/zolan/index.html' do
content "This file is generated from Chef"

 Cookbook files resource: You can put your cookbook files inside files directory in your

cookbook and use them in your recipe.
cookbook_file '/zolan/index.html' do
source 'index2.html'
user 'root'
notifies:restart, 'service[httpd]'

package resource: Installing and removing packages from nodes

package 'wget' do

 Service resource: Managing services on nodes

service 'httpd' do
action: start

working with  second recipe: Create a second recipe inside your recipe directory recipe/second_recipe.rb and put your configuration on it. You can run your second recipe after specifying the cookbook

# chef-client --local-mode -o 'recipe[MyFirstCookBook::second_recipe]'

It’s really a good practice to separate cookbook into multiple recipes and them include them inside a default recipe.

include_recipe 'zGeneric::second_recipe'

Cookbook attributes: It’s a way to assign values to one or more attributes. It must be in attributes folder. It will automatically incorporates in node objects and any recipe can use it by referencing the attributes. create a file  attributes/default.rb and configure your attributes into it.

node.default['lampsrv']['KeepAlive'] = "On"
node.default['lampsrv']['KeepAliveTimeout'] = "30"

We have crated some attributes which we can define some Apache related settings. Now we can use this attributes inside a recipe.Modify your recipe

log node['lampsrv']['KeepAlive']
log node['lampsrv']['KeepAliveTimeout']

Run your cookbook and you get something similar result

# chef-client --local-mode -o 'recipe[MyFirstCookBook]'
 * log[On] action write
 * log[30] action write

Note: It’s a best practice to use attributes inside a template and use them for generating configuration.

Cookbook templates: A cookbook template is an Embedded Ruby (ERB) template that is used to dynamically generate static text files.
Let’s crate a file templates/default/default.erb and append below code. We have already created the attributes in above example.

ServerLimit <%= node['lampsrv']['KeepAlive']%>
KeepAliveTimeout <%= node['lampsrv']['KeepAlive']%>

This template is created with attributes in a cookbook and will automatically generate the configuration. This configuration can be use inside a recipe. Create a template recourse inside your recipe file

template '/etc/httpd/conf.d/enhancement.conf' do
source 'default.rb'
notifies: restart, 'service[httpd]'

Note: Cookbook files and templates are the same thing except you can modify the content of template dynamically. It’s a best practice to use dynamic content or configuration files into templates and binary packages or static files into templates.

Cookbook roles: role attributes take precedence over the default attributes and override the default settings. Each role consist of attributes and a run list.
Create a roles file inside role directory name KeepAliveOff.rb

'lampsrv' => {
'KeepAlive" => "Off",
'KeepAliveTimeout' => 0, }

Run your cookbook with defined roles

# chef-client --local-mode -o 'role[KeepAliveOff]'

All this are pretty basics things but help us to understand the basic architecture of Cookbooks and recipes.