Getting the Chef to cook for us!

We have three things here, in the earlier post, we saw how chef was installed on the workstation.

1. Enterprise Chef Server - Which is the main server which will be orchestrating the entire process.

2. Node -  this is the Virtual machine which will be hosting our app the one which will be carrying our payload. It will have the chef-client installed on it, which will be communicating with the Enterprise Chef server and controlling the configuration of the node or the VM.

3. Workstation - your laptop, that is the machine used to configure the Enterprise server and control the nodes. This is where we had installed chef in our earlier exercise.

Before we get started we would need to get a login name and the starter kit from the Chef Enterprise Server.

  • Go to this link and register. Remember that you will be using the organisation name, as we will be using it.
  • Once registered, signed in!
  • Download the Starter Kit.
  • Unzip the kit, this is the knife tool
  • rename the folder to "chef-repo" and move it into your home folder

TIP: have sublimetext installed on your machine, so that its easier to edit the configuration files. You could use this link if you are on Ubuntu.

Using Sublimetext lets open the folder of the chef-repo and also the knife.rb the ruby file which is the config file for knife and examine it's contents

When ever we are going to work on a terminal next, it would be within the chef-repo directory

so we go into the terminal and put in the command

knife --version

to ensure that that knife is ready for us to use.

and confirm the version number.

And to confirm if the configuration is perfect and the client is able to connect to the server

knife client list 

gives us the organisation name confirming that your knife is connected.

More information about Knife file configuration can be found on this link.

Checking it all into Git

In the chef-repo, we initiate Git and then check in the code, you can refer this post to get a hang of Git.

Looking at our Organisations!

Log into this link.
And we get the organisations by clicking on the Administration tab. 

and we can do the following from this page by clicking on the wrench on the right hand corner.

Enough of setting things up now, time for some action!

Getting a node or VM to try stuff out!

We will use Vagrant, to create our nodes. To know more about Vagrant you can see some of the earlier post "Vagrant - Simplified and mastered!" and some more in this series.

We see that within the chef-repo there is a Vagrantfile which is the config file to create a node or a VM.

So we will just bring up a VM by using the "vagrant up" command.

vagrant up

to know the details of the node
vagrant ssh-config 

To connect to this server

ssh vagrant@ -p 2222

and we see on how to connect to it. Or even vagrant ssh comments also helps us in connecting to our instance. 

Bootstrapping a node!

Is nothing but installing the chef-client on the node, there are two ways of doing it one of them is the attended and the other unattended. 

The default for this approach assumes that node can access the Chef website so that it may download the chef-client package from that location. 
The omnibus installer will detect the version of the operating system, and then install the appropriate version of the chef-client using a single command to install the chef-client and all of its dependencies, including an embedded version of Ruby, RubyGems, OpenSSL, key-value stores, parsers, libraries, and command line utilities. 
The omnibus installer puts everything into a unique directory (opt/opscode/) so that the chef-client will not interfere with other applications that may be running on the target machine. Once installed, the chef-client requires a few more configuration steps before it can perform its first chef-client run on a node.

take from this place

knife bootstrap FQDN/IP address
-x ssh_username
-P ssh_password
-p ssh_port
-N "nickname to refer to latter"

all of this put together

knife bootstrap --sudo -x vagrant -P vagrant -p 22 -N "vm1"

its sheer joy to see it come up!

Troubleshooting: In case you get the error such as this on vagrant up
'require': cannot load such file -- log4r (LoadError)
this comes up when Vagrant is installed using apt-get. Hence download and install vagrant from the download page.

Going back to the Chef Enterprise server console we see that this target has been added.

We see the "vm1" added and below is the complete and detailed profile, which has come due to the system profiler called Ohai running on the node!

we can run ohai on our machine and see the amount of details its throws up on the screen.

Creating our First Cookbook

Definition from here.
A cookbook is the fundamental unit of configuration and policy distribution. Each cookbook defines a scenario, such as everything needed to install and configure MySQL, and then it contains all of the components that are required to support that scenario, including:
  • Attribute values that are set on nodes
  • Definitions that allow the creation of reusable collections of resources
  • File distributions
  • Libraries that extend the chef-client and/or provide helpers to Ruby code
  • Recipes that specify which resources to manage and the order in which those resources will be applied
  • Custom resources and providers
  • Templates
  • Versions
  • Metadata about recipes (including dependencies), version constraints, supported platforms, and so on
Let's try to write a cookbook to bring up a webserver for this, we would do the following:-

  1. Install Apache
  2. Start the service
  3. Make sure it boots when the machine starts
  4. Customise the home page.

Creating the cookbook by the name "apache" by running the below command on the workstation and in the chef-repo directory

knife cookbook create apache

This creates a new folder called apache under cookbooks and we will edit the default recipe 

before we start editing this file, lets take a look at what chef "Resources" are

  • A resource is a key part of a recipe. 
  • A resource defines the actions that can be taken, such as when a package should be installed, whether a service should be enabled or restarted, which groups, users, or groups of users should be created, where to put a collection of files, what the name of a new directory should be, and so on. 
  • Each resource is processed in the same order as they appear in a recipe. 
  • The chef-client ensures that the same actions are taken the same way everywhere and that actions produce the same result every time. 
  • A resource is implemented within a recipe using Ruby.
  • Where a resource represents a piece of the system (and its desired state), a provider defines the steps that are needed to bring that piece of the system from its current state into the desired state. These steps are de-coupled from the request itself. The request is made in a recipe and is defined by a lightweight resource. The steps are then defined by a lightweight provider.
A resource is a Ruby block with four components: a type, a name, one (or more) attributes (with values), and one (or more) actions. The syntax for a resource is like this:
type "name" do
   attribute "value"
   action :type_of_action
For example, a resource that is used to install a tar.gz package for version 1.16.1 may look something like this:
package "tar" do
  version "1.16.1-1"
  action :install
Every resource has its own set of actions and attribute. Most attributes have default values. Some attributes are available to all resources, for example some attributes are used to send notifications to other resources, whereas others are used to set up conditional execution rules.
All actions have a default value. Only non-default behaviours of actions and attributes need to be specified. For example, the package resource’s default action is to install and the name of the package defaults to the "name" of the resource, therefore it is possible to write a resource block like this:
package "tar"
and the chef-client will use the default action (:install) to install the tar package. refer this for more

so we will have the following now

package "apache2" do
    action :install

now that we want this service to be enabled even in reboot.

service "apache2" do
    action [:start, :enable]

next we will need to write the home page, so we will use the resource "cookbook_file" which is
The cookbook_file resource is used to transfer files from a sub-directory of the files/ directory in a cookbook to a specified path that is located on the host running the chef-client or chef-solo. 
cookbook_file "/var/www/index.html" do
    source "index.html"
    mode "0644"

now in the above we are asking chef to take the file called index.html and push it to the node

now to push this cookbook to the node, we use the command

knife cookbook upload apache

and to take a look at what has been uploaded

Now about the recipes 

A recipe: Must be added to a run-list before it can be used by the chef-client
Is always executed in the same order as listed in a run-list

What's a RunList now!

Again by definition:-

A run-list is an ordered list of recipes and/or roles that are run in an exact order. 
A run-list is always specific to the node on which it runs, though it is possible for many nodes to have run-lists that are similar or even identical. 
The items within a run-list are maintained using Knife and are uploaded to the server and stored as part of the node object for each node. 
The chef-client always configures a node in the exact order specified by its run-list and will never run the same recipe twice.
A recipe is the most fundamental configuration element within the organization. 

So we see that a recipe in itself is of now use unless we've added it to the runlist.

and now log into the VM or the node and run the command

sudo chef-client

yes, it will give an error, as the apt-get cache is outdated and we would need to update it, but let's automate that, instead of having a manual process to do this and at the same time see how order matters in runlists. We will create one more recipe in a new cookbook for apt.

We create the cookbook called apt_cache_update, then add a recipe and upload it.

and go into the Chef management console and add the newly created recipe and add it to being the first one in the order. 

save and now lets run the chef-client on the node to see what happens!

and finally when we try to access use a browser to get this webpage on port 8080 we get the home page that we created!