Getting started with chef cookbooks as an app dev with test-kitchen + docker, part 1

    ## How do you get started with chef cookbooks as an app dev?

    My first time approaching Chef was after doing Android for about 2 years. Whether you're working on the front-end or backend or even on Mobile, the overall workflow of your application is the same.

    * Make changes to your application locally
    * Write unit and/or integration tests to verify your changes
    * Deploy & verify your changes to a test environment
    * Deploy & verify your changes to a prod environment

    The setup that I first worked with wasn't too well aligned with that. Feedback loops involved deploying cookbooks to chef-server and re-converging instances in a live environment. Process prevented untested code from making it to production, but it did happen.

    The following is my attempt at creating a quick feedback loop when working with cookbooks that makes it easy to approach as an app developer.

    ## Create the source files for your cookbook
    You want to create a hello world cookbook to configure a server and then verify that it works.

    metadata.rb

    ```
    name "helloworld"
    maintainer "me"
    maintainer_email "me@me"
    license "Apache 2.0"
    description "helloworld"
    long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
    version "0.0.1"
    ```

    README.md

    ```
    hello world cookbook
    ```

    recipes/default.rb

    ```
    :;Chef::Log.error 'Hello World'
    ```

    ## "Build" a cookbook

    Enter test-kitchen. It helps you create different types of machines, and execute scripts and tests to verify your configuration.

    We can start by creating a .kitchen.yml file containing the configuration we need to get going.

    .kitchen.yml

    ```
    ---
    driver:
    name: docker

    provisioner:
    name: chef_zero
    require_chef_omnibus: latest

    platforms:
    - name: trusty
    driver_config:
    image: ubuntu:14.04
    platform: ubuntu

    suites:
    - name: default
    run_list:
    - "recipe[helloworld::default]"
    ```

    In this file, we have

    - configured the Docker driver. test-kitchen will create a docker container, SSH into it, and execute your test suite. The driver configuration here + the docker image ubuntu-upstart is necessary to work around known issues with docker and upstart/systemd.
    - defined your chef context - this could be chef_zero or chef-solo, they're essentially the same except chef_zero pretends to be a chef-server, whereas chef-solo knows he's not.
    - defined the platform we want to run on. for the sake of example, we'll run ubuntu 14.04 from the docker registry
    - defined the test suite

    We're ready to run this through kitchen now. Add a Gemfile.

    Gemfile

    ```
    source 'https://rubygems.org'

    gem 'test-kitchen'
    gem 'kitchen-docker'
    gem 'serverspec'
    ```

    Run bundle install and then bundle exec kitchen converge. Test kitchen will now start the process of creating a container from your chosen image, it will SSH in, and install the chosen version of chef, and then finally run the recipe you defined in the test suite.

    ## Test your cookbook

    You can consider converging to be the equivalent to "running" or "building" a cookbook. If you have a successful converge and you see your Log message "helloworld", then congrats - you've got a hello world cookbook that you can test like any other application. You've created a project, you ran/built it, and you verified your changes.

You might be interested in…

Menu