Anatomy of a chef solo project - Reliably Deploying Rails Applications: Hassle free provisioning, reliable deployment (2014)

Reliably Deploying Rails Applications: Hassle free provisioning, reliable deployment (2014)

5.0 - Anatomy of a chef solo project

Overview

In this chapter will cover creating a simple Chef project and look at how the chef terminology relates to the folder structure.

Creating a project

Our first step is to install the tools needed to create and manage a chef project.

Create a new folder to contain your chef project and move into it;

1 mkdir my_chef_projects

2 cd my_chef_projects

Now create a new Gemfile within my_chef_projects and enter the following:

1 source 'https://rubygems.org'

2

3 gem 'knife-solo', '0.3.0'

4 gem "chef", "~> 11.10.0"

5 gem 'chef-zero', '1.7.2'

6 gem "berkshelf", "~> 2.0.14"

Then run

1 bundle install

To install Chef, Knife Solo and Berkshelf. It’s important to use the Gemfile to ensure that the versions installed are the versions which this book has been tested with. Both the Berkshelf and Chef gems are regularly updated so using an unsupported version may lead to unexpected behaviour.

Terminology

Recipe

Chef definition for installing a single component, e.g. ruby, mysql-server, Monit etc

Cookbook

A selection of recipes, so for example a “mysql” cookbook might include a recipe for a mysql server and another one for a mysql client.

Node

A remote server you’re provisioning

Role

A combination of recipes which when applied to a node, allows it to perform a particular role.

For example a “Postgres Server” role might include recipes for installing postgres-server as well as installing and configuring the firewall and setting up suitable monitoring for the server process.

You can sort of think of a role as an equivalent to a mixin in ruby. It allows you to create a piece of re-usable functionality that can later be applied to many nodes.

Data Bag

A JSON file which contains meta data used by recipes, for example lists of users to be created and the valid public keys for authenticating as them.

Chef Repository

A collection of node and role definitions

Creating a repository

Once the Gem installation completes you’re ready to create an empty chef solo project using knife. Execute the following command:

1 bundle exec knife solo init my_first_chef_repo

warning

bundle exec

bundle exec ensures that the version of the gems used matches the version defined in the Gemfile. It’s important that you always use bundle exec when running knife commands to ensure you’re using gem versions which have been tested with this book.

You should see output similar to the following:

1 WARNING: No knife configuration file found

2 Creating kitchen...

3 Creating knife.rb in kitchen...

4 Creating cupboards...

5 Setting up Berkshelf...

You can then cd into the newly created my_first_chef_repo where you’ll see a directory structure like the following:

1 -my_first_chef_repo/

2 -.chef

3 - knife.rb

4 -cookbooks

5 -data_bags

6 -nodes

7 -roles

8 -site_cookbooks

information

The Gemfile

I suggest you copy the Gemfile from my_chef_projects into my_first_chef_repo. If you don’t, bundle exec from within my_first_chef_repo will still work as it will just use the Gemfile from the parent directory but you lose the flexibility of specifying different gem versions or additional gems per repository.

knife.rb

Knife is the command line utility which allows us to interact with chef on our remote server.

Knife solo adds extra commands for interacting directly with the server we’re provisioning from our development workstation (rather than via a central chef server)

knife.rb contains the knife configuration options which are specific to our repository. This is more important when working with a centralised chef server which we aren’t so for our purposes we’ll treat this as the primary (and only) configuration point for knife.

Documentation for the full range of options available is at

http://docs.opscode.com/config_rb_knife.html

they key ones for us are:

cookbook_path - this is an array of paths relative to the root repository directory where the cookbooks referenced in roles and/ or node definitions are located.

node_path - path relative to the root of the repository where node definitions are stored

role_path - path relative to the root directory where role definitions are stored

data_bag_path - path relative to the root directory where data_bags are stored.

In general we can leave these at their default values.

cookbooks vs site_cookbooks

Here we’ll use the cookbooks directory to store other peoples cookbooks which we install using Berkshelf (covered later) and site_cookbooks to contain our own custom cookbooks.

It’s important not to use cookbooks for none Berkshelf ones for the simple reason that it is wiped every time we run knife solo cook! That means that any changes we make in here, will not be persisted.

Next we’ll look at the anatomy of an individual recipe.