Chef - Test Kitchen Setup

Test Kitchen is Chef’s integrated testing framework. It enables writing test recipes, which will run on the VMs once they are instantiated and converged using the cookbook. The test recipes run on that VM and can verify if everything works as expected.

ChefSpec is something which only simulates a Chef run. Test kitchen boots up real node and runs Chef on it.

Step 1 − Install test kitchen Ruby gem and test kitchen vagrant gem to enable test kitchen to use vagrant for spinning up test.

$ gem install kitchen 
$ gem install kitchen-vagrant 

Step 2 − Set up test kitchen. This can be done by creating .kitchen.yml in the cookbook directory.

driver_plugin: vagrant 
   require_chef_omnibus: true 
   - name: ubuntu-12.04 
      box: opscode-ubuntu-12.04 
   - name: default 
   - recipe[minitest-handler] 
   - recipe[my_cookbook_test] 
attributes: { my_cookbook: { greeting: 'Ohai, Minitest!'} } 

In the above code, one part defines that vagrant needs to spin up the VMs and it defines that you want Omnibus to install Chef on the target node.

The second part defines which platform you want to test the cookbooks. Vagrant will always create and destroy new instances. You do not have to fear about the side effects with vagrant VMs you spin up using Vagrant file.

Test kitchen can be considered as a temporary environment that helps to run and test cookbooks in a temporary environment that is similar to production. With test kitchen on, one can make sure that the given piece of code is working, before it is actually getting deployed on to testing, preproduction, and production environment. This feature of test kitchen is followed by many organizations as a set before putting the cookbooks in an actual working environment.

Test Kitchen Workflow

Following are the steps involved in Test Kitchen Workflow.

Kitchen Workflow

Creating a Cookbook Using Chef

Use the following code to create a cookbook.

$ chef generate cookbook motd_rhel 
Installing Cookbook Gems: 

Compiling Cookbooks... 
Recipe: code_generator::cookbook
   * directory[C:/chef/cookbooks/motd_rhel] action create
      - create new directory C:/chef/cookbooks/motd_rhel
   * template[C:/chef/cookbooks/motd_rhel/metadata.rb] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/metadata.rb
      - update content in file C:/chef/cookbooks/motd_rhel/metadata.rb from none to 
      d6fcc2 (diff output suppressed by config)
   * template[C:/chef/cookbooks/motd_rhel/] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/
      - update content in file C:/chef/cookbooks/motd_rhel/ from none to 50deab
         (diff output suppressed by config)
   * cookbook_file[C:/chef/cookbooks/motd_rhel/chefignore] action create
      - create new file C:/chef/cookbooks/motd_rhel/chefignore
      - update content in file C:/chef/cookbooks/motd_rhel/chefignore from none to 15fac5
         (diff output suppressed by config)
   * cookbook_file[C:/chef/cookbooks/motd_rhel/Berksfile] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/Berksfile
      - update content in file C:/chef/cookbooks/motd_rhel/Berksfile from none to 9f08dc
         (diff output suppressed by config)
   * template[C:/chef/cookbooks/motd_rhel/.kitchen.yml] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/.kitchen.yml
      - update content in file C:/chef/cookbooks/motd_rhel/.kitchen.yml
         from none to 49b92b (diff output suppressed by config)
   * directory[C:/chef/cookbooks/motd_rhel/test/integration/default/serverspec]
      action create 
      - create new directory 
   * directory[C:/chef/cookbooks/motd_rhel/test/integration/helpers/serverspec]
      action create 
      - create new directory 
   * cookbook_file
      action create_if_missing
      - create new file 
      - update content in file
            from none to d85df4 (diff output suppressed by config)
   * template
      [C:/chef/cookbooks/motd_rhel/test/integration/default/serverspec/defaul t_spec.rb]
      action create_if_missing
      - create new file
      - update content in file
            from none to 3fbdbd (diff output suppressed by config)
   * directory[C:/chef/cookbooks/motd_rhel/spec/unit/recipes] action create
      - create new directory C:/chef/cookbooks/motd_rhel/spec/unit/recipes
   * cookbook_file
      [C:/chef/cookbooks/motd_rhel/spec/spec_helper.rb] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/spec/spec_helper.rb
      - update content in file
         C:/chef/cookbooks/motd_rhel/spec/spec_helper.rb from none to 587075
            (diff output suppressed by config)
   * template
      action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/spec/unit/recipes/default_spec.rb
      - update content in file
            from none to ff3b17 (diff output suppressed by config)
   * directory[C:/chef/cookbooks/motd_rhel/recipes] action create
      - create new directory C:/chef/cookbooks/motd_rhel/recipes
   * template[C:/chef/cookbooks/motd_rhel/recipes/default.rb] action create_if_missing
      - create new file C:/chef/cookbooks/motd_rhel/recipes/default.rb
      - update content in file
         C:/chef/cookbooks/motd_rhel/recipes/default.rb from none to c4b029
            (diff output suppressed by config) 
   * execute[initialize-git] action run 
      - execute git init . 
   * cookbook_file[C:/chef/cookbooks/motd_rhel/.gitignore] action create
      - create new file C:/chef/cookbooks/motd_rhel/.gitignore
      - update content in file C:/chef/cookbooks/motd_rhel/.gitignore from none to 33d469
         (diff output suppressed by config)
   * execute[git-add-new-files] action run
      - execute git add .
   * execute[git-commit-new-files] action run 
      - execute git commit -m "Add generated cookbook content" 

Following is the Created Cookbook Structure as an output of the above code.


Test Kitchen Configuration File

.kitchen.yaml file

   name: vagrant 
   name: chef_zero 
# verifier: 
# name: inspec 
# format: doc 
   - name: ubuntu-14.04 
   - name: default 
      - recipe[motd_rhel::default] 

Drivers − It specifies the software which manages the machine.

Provisioner − It provides specification on how Chef runs. We are using chef_zero because it enables to mimic a Chef server environment on the local machine. This allows to work with node attributes and Chef server specifications.

Platform − This specifies the target operating system.

Suites − It defines what one wants to apply on the virtual environment. Here, you define multiple definition. It is the location where you define the run list, which specifies which recipe to run and in which sequence we need to run.

Running the Commands in Sequence

Kitchen List

$ kitchen list 
Instance  Driver  Provisioner Verifier   Transport Last Action 
ubuntu-1404 Vagrant ChefZero   Busser       Ssh   <Not Created> 

Kitchen Create

$ kitchen create
-----> Starting Kitchen (v1.4.2)
-----> Creating <default-centos-72>...
      Bringing machine 'default' up with 'virtualbox' provider...
      ==> default: Box 'opscode-centos-7.2' could not be found.
         Attempting to find and install...
      default: Box Provider: virtualbox
      default: Box Version: >= 0
      ==> default: Box file was not detected as metadata. Adding it directly...
         ==> default: Adding box 'opscode-centos-7.2' (v0) for provider: virtualbox
         default: Downloading:
         Vagrant instance <default-centos-72> created.
         Finished creating <default-centos-72> (3m12.01s).
         -----> Kitchen is finished. (3m12.60s)

Kitchen Converge

$ kitchen converge 
-----> Converging <default-centos-72>...        
      Preparing files for transfer        
      Preparing dna.json        
      Resolving cookbook dependencies with Berkshelf 4.0.1...
      Removing non-cookbook files before transfer       
      Preparing validation.pem        
      Preparing client.rb 
-----> Chef Omnibus   installation detected (install only if missing)        
      Transferring files to <default-centos-72>       
      Starting Chef Client, version 12.6.0        
      resolving cookbooks for run list: ["motd_rhel::default"]
      Synchronizing Cookbooks: - motd_rhel (0.1.0)       
      Compiling Cookbooks...       Converging 1 resources        
      Recipe: motd_rhel::default        (up to date)         
      Running handlers:       Running handlers complete       
      Chef Client finished, 0/1 resources updated in 01 seconds        
      Finished converging <default-centos-72> (0m3.57s). 
      -----> Kitchen is finished. (0m4.55s) 

Testing Setup

Kitchen login is used to test if the testing VM is provisioned correctly.

$ kitchen login 
Last login: Thu Jan 30 19:02:14 2017 from 
hostname:  default-centos-72 
fqdn:      default-centos-72 
memory:    244180kBcpu count: 1 

Finally Exit

$ exit 
Connection to closed. 

Destroying Setup

$ Kitchen destroy 
-----> Starting Kitchen (v1.4.2) 
-----> Destroying <default-centos-72>...       
   ==> default: Forcing shutdown of VM...        
   ==> default: Destroying VM and associated drives...        
   Vagrant instance <default-centos-72> destroyed.        
   Finished destroying <default-centos-72> (0m4.94s). 
-----> Kitchen is finished. (0m5.93s) 
Kickstart Your Career

Get certified by completing the course

Get Started