This demo will walk you through using Chef 12 inside CloudLab's experiment

Autor: Dmitry Duplyakin


Date: 09/09/2015


  • Chef12Slice Profile 
    • ​Profile with Chef Server, Workstation, and Clients. See more information in the profile description
  • Emulab's Chef Repository
    • ​Repository of recommended (carefully developed and well tested) cookbooks. It will be cloned onto the head node on the instance of the profile
  • Chef Supermarket (collection of community developed cookbooks)
    • We will download and use the NFS cookbook in this demo


Launching an Experiment

  • Instantiate Chef12Slice 
  • Wait until it says "Your experiment is ready"

Getting Started

  • After a few minutes, when Chef is fully configured, you should get an email: 
  • After receiving this email, log into the head node
    • E.g., 
  • Switch to root:
ssh -p 22
sudo su - 

Getting Started

  • There are two nodes in the Chef environment and no cookbooks by default
root@head:~# knife cookbook site install nfs
Installing nfs to /chef-repo/cookbooks
Creating pristine copy branch chef-vendor-nfs
Cookbook saved: /chef-repo/cookbooks/nfs.tar.gz
Uncompressing nfs version 2.2.5.
root@head:~# knife cookbook upload -a
Uploading line         [0.6.2]
Uploading nfs          [2.2.5]
Uploading ohai         [2.0.1]
Uploading sysctl       [0.6.2]
Uploaded all cookbooks.
root@head:~# knife cookbook list
line         0.6.2
nfs          2.2.5
ohai         2.0.1
sysctl       0.6.2
  • Get the NFS cookbook (and its dependencies) from Chef Supermarket
  • Upload all cookbooks to Chef server (on head) and check

All cookbooks are in /chef-repo/cookbooks/. NFS cookbook:

root@head:~# knife node list
root@head:~# knife cookbook list


Configuring NFS Server: Role

  • Create a role for NFS server and upload it to the server 
root@head:~# cd /chef-repo/roles/
root@head:/chef-repo/roles# vi nfs_server.rb

name "nfs_server"
description "Role applied to the system that should be an NFS server."
  "nfs" => {
    "packages" => [ "portmap", "nfs-common", "nfs-kernel-server" ],
    "port" => {
      "statd" => 32765,
      "statd_out" => 32766,
      "mountd" => 32767,
      "lockd" => 32768
run_list [ "nfs::server" ]

root@head:/chef-repo/roles# knife role from file nfs_server.rb 
Updated Role nfs_server!
root@head:/# knife node run_list add head "role[nfs_server]"
  run_list: role[nfs_server]
  • Assign this role to head

Configuring NFS Server: Recipe

  • Create a recipe for exporting /exports from head and upload the updated nfs cookbook to the server (to make the new recipe available)
root@head:/# knife node run_list add head "recipe[nfs::export]"
  • Assign this recipe to head
root@head:/chef-repo/roles# cd /chef-repo/cookbooks/nfs/recipes
root@head:/chef-repo/cookbooks/nfs/recipes# vi export.rb

# Cookbook Name:: nfs
# Recipe:: export
directory '/exports' do
  action :create
nfs_export "/exports" do
  network ''
  writeable false
  sync true
  options ['no_root_squash']

root@head:/chef-repo/cookbooks/nfs/recipes# knife cookbook upload nfs
Uploading nfs            [2.2.5]
Uploaded 1 cookbook.

Configuring NFS Server: Run

  • Check what is assigned to run on head
root@head:/# chef-client 
Starting Chef Client, version 12.0.3
resolving cookbooks for run list: ["nfs::server", "nfs::export"]
Synchronizing Cookbooks:
  - nfs
  - line
  - sysctl
  - ohai
Compiling Cookbooks...

Running handlers:
Running handlers complete
Chef Client finished, 14/22 resources updated in 9.592334135 seconds
  • Trigger the configuration process locally, on head (in Chef terms: converge the node)
root@head:/chef-repo/cookbooks/nfs/recipes# knife node show head
Node Name:   head
Environment: _default
Run List:    role[nfs_server], recipe[nfs::export]
Platform:    ubuntu 14.04      
root@head:/# service nfs-kernel-server status
nfsd running
  • NFS server is running now:

Configuring NFS Client

root@head:~# knife node run_list add node-1 "recipe[nfs]"
  run_list: recipe[nfs]

Typically, this command is used in the form: knife node run_list add <node> "recipe[<cookbook>::<specific recipe>]". If only the name of the cookbook is specified in square brackets like in the example above, the default recipe is used (in this particular case, /chef-repo/cookbooks/nfs/recipes/default.rb

root@head:/# knife node show node-1
Node Name:   node-1
Environment: _default
Run List:    recipe[nfs]
Platform:    ubuntu 14.04
  • Check what is assigned to run on node-1
  • Assign nfs cookbooks to node-1
root@head:/# ssh node-1 chef-client
[2015-09-09T10:43:14-05:00] INFO: Forking chef instance to converge...
[2015-09-09T10:43:14-05:00] INFO: *** Chef 12.4.1 ***
[2015-09-09T10:43:14-05:00] INFO: Chef-client pid: 4587
[2015-09-09T10:43:15-05:00] INFO: Run List is [recipe[nfs]]
  • Converge node-1 via ssh

Mounting and Testing

root@head:/# ssh node-1 "mkdir /imports"
root@head:/# ssh node-1 "mount head:/exports /imports"
  • Mount /exports from head on node-1 under /imports (via ssh) 

These commands can form a client-side recipe in the nfs cookbook if such organization if preferred.

root@head:/# ls /exports/
root@head:/# ssh node-1 "ls /imports"
root@head:/# touch /exports/test
root@head:/# ssh node-1 "ls /imports"
  • Testing NFS export/mount - add a file on head and see it on node-1 


​In this demo we:

  • Used Chef12Slice with Chef Server, Workstation (knife utility), and Clients (on head and node-1
  • Downloaded and installed a community cookbook (nfs)
  • Created a role (nfs_server) and assigned it to a node
  • Created a recipe (nfs::export) and assigned it to a node
  • Converged two nodes (head and node-1 via ssh) to install and configure both server and client sides for NFS
  • Tested the NFS installation
  • Performed all these steps essentially without leaving the head node


Final remark: 

Currently the Emulab's Chef repo ( is empty. In the future, when the repo is populated, we can reduce the number of manual steps (e.g., avoid creating roles and recipes by hand - they will be cloned along with other artifacts in the repo). Then, the basic workflow will go like this: clone the repo, assign roles/recipes to nodes, and converge nodes. All these steps have been shown in this demo. 


Email if you have any questions.