Seamless Chef

Seamless Chef

Cyclid was built with non-traditional workflows in mind. For example,
Continuous Integration for your Chef cookbooks. In this article I’ll show you how Cyclid can help make your Chef CI seamless and painless.

Most of your CI pipeline for a Chef cookbook will involve testing; and there’s a lot of tools to test your Chef cookbook! Each type of tool can test a different layer of your cookbook.

  1. Syntax and Style Analysis
  2. Unit Testing
  3. Acceptance Testing
  4. Integration Testing

Syntax and Style Analysis is covered by Rubocop, in the form of Cookstyle. Rubocop is a static analysis tool, and Cookstyle provides consistent default rules for Chef cookbooks.

Unit testing is provided by RSpec, in the form of ChefSpec.

Acceptance testing involves running your cookbook in a sandbox and testing the outcome. This normally means running Test Kitchen and then testing with either Serverspec, or the newer Inspec framework. Normally you’d choose Inspec for new cookbooks, but there can be good reasons to still use Serverspec: it’s up to you!

Integration Testing is the last step; it’s mostly out of scope for a normal CI pipeline. Normally you’d upload your cookbook to an Integration or Staging environment and then have something else run a series of tests.

The Acceptance Testing Challenge

The good news is that the first two steps are very easy to do with almost any CI system. The really good news is that Acceptance Testing is easy to do too, if you use Cyclid!

Why is Acceptance Testing traditionally the hardest part to integrate into your Continuous Integration? Because you need to create a sandbox. The sandbox is normally a virtual machine or container, but if your CI system is already running in a container, where do you create your sandbox? A common solution is to use an external Cloud provider and embed the API credentials in each cookbook test suite, but that has some obvious problems with credentials management and creates an external dependency for your cookbook CI pipeline.

There is a better way. Hosted Cyclid runs your CI jobs on real virtual machines, and real virtual machines allow you to create and run a container. The kitchen-dokken driver for Test Kitchen makes it simple to run your Test Kitchen sandbox in a Docker container, all inside of your Cyclid Build Host virtual machine!

Getting set up

Thanks to the efforts of Chef, we only really need to install the Chef Development Kit (ChefDK) and Docker. We’ll need to make sure curl is installed too (which we’ll use to install ChefDK).

---
name: example-chef-project
environment:
  os: ubuntu_trusty
  packages:
  - git
  - curl
  - docker.io

(Note that the Docker package is named “docker.io” in Ubuntu Trusty for historical reasons). We’ll also need a Stage to perform the ChefDK installation:

- name: install-chefdk
  steps:
  - action: script
    script:
    - '#!/bin/bash -x'
    - curl -s -L -O https://packages.chef.io/files/stable/chefdk/1.5.0/ubuntu/14.04/chefdk_1.5.0-1_amd64.deb || exit 1
    - sudo dpkg -i chefdk_1.5.0-1_amd64.deb || exit 1

That’s all we need! The rest of our Job can then concern itself with testing our cookbook, which might look something like this:

- name: lint
  steps:
  - action: command
    cmd: chef exec cookstyle
    path: '%{workspace}/my-cookbook'
- name: chefspec
  steps:
  - action: command
    cmd: chef exec rspec
    path: '%{workspace}/my-cookbook'
- name: test-kitchen
  steps:
  - action: command
    cmd: chef exec kitchen test --no-color
    path: '%{workspace}/my-cookbook'
sequence:
- stage: install-chefdk
  on_failure: failure
- stage: lint
  on_failure: failure
- stage: chefspec
  on_failure: failure
- stage: test-kitchen
  on_success: success
  on_failure: failure

You need to make sure that you’ve configured Test Kitchen to use kitchen-dokken, of course. That’s also easy; from the documentation, your .kitchen.yml file should look something like this:

---
driver:
  name: dokken
  chef_version: latest

transport:
  name: dokken

provisioner:
  name: dokken

Here’s one we made earlier

Of course, we’ve put all of this together for you in a simple example project. If you want to see how this works in practice, sign up for a free Hosted Cyclid account and run the example job. It’s so simple you’ll wonder why it’s seemed so hard all this time!