With Chef, you can manage your servers by writing code, not by
running commands; integrate tightly with your applications,
databases, LDAP directories; easily configure applications that
require knowledge about your entire infrastructure; and create
perfect clones of QA environments, pre-production (staging) and
production environments, etc.
If these notes appear schizophrenic, it's because they are. I'm trying
to consume Chef at work and at home, the learning is somewhat painful
because I'm not a Ruby guy at all. Someday, after this has come together,
I'll try to consolidate and un-dummify these notes.
Note: I'm running Ubuntu Precise Pangolin in my examples.
I'm using a subdirectory named chef in the root directory of my
own development host as a place to work from. Names and passwords used
in these notes are taken from great French chefs, including me
;-)
The Chef server is not really a server at all. It doesn't do anything
except publish. It stores data about nodes, roles, and user-provided data that's
retrieved via essentially API calls. It provides a search API too.
Every time a Chef client runs, typically on one of the managed nodes, the
following occurs:
The node is built.
Cookbooks are synchronized.
The resource collection is compiled.
The node is configured.
Notices are given and exceptions handled.
The Chef node is a Ruby object that represents the host (or machine) that's
being configured. It has attributes and a run list. The object is rebuilt every
time the Chef client is run, merging input from the local host, the Chef API and
attributes and run lists from roles.
Cookbooks contain data including recipes, attributes and more. They are
requested from the Chef server where they reside.
The resource collection is a list of resources that must be used to configure
the node. This includes the results of evaluating recipes and attributes. Once
resource collections are compiled, the required actions are taken by the
providers and the node is saved back to the server where it's indexed for
searching.
Chef Solo is where you don't necessarily install a server. Instead, you develop
and test-deploy your recipes to your local development host. Later, you can use
those recipes on any Chef server. On the Chef server, you invoke the chef-colo
command and the server runs the recipes on all the nodes specified.
Here are some instructions that assume that a Chef server is already set up and
running, and that Chef clients are set up. The following configuration file is
used in these steps. Prior to these steps, stuff is set up on the server (in its
Chef repository) that's not shown here, but referred to in this file. Please see
_________.
The Chef server URL below is the one you supplied during the installation of the
Chef server.
Using NTP, synchronize time between clients and server. Chef will error out if
the drift exceeds 15 minutes. (See Notes on NTP.)
Get root.
Create /etc/chef and make that the current working directory.
Run knife configure client, knife.rb:
# knife.rb ./
This will generate client.rb and validation.pem. Edit client.rb
and change log-level from "info" to "debug".
Replace validation.pem with the one your Chef server as these must match
perfectly.
Run chef-client.
# chef-client
Unless everything is magically perfect, this will produce numerous errors that must
be fixed. Frequently, these are errors in the configuration file, client.rb,
such as a failure to find the server. In my observation, Chef will not make use of
anything in /etc/hosts, so hard IP addresses must be used. I don't know
whether it uses DNS as my set-ups have always been using ad hoc internal ESXi
VMs or scrap hardware, never formal hosts noted in DNS tables.
Now go to the Chef web interface to make sure that node is registered. You can do
this from a browser running on your development host, which would not typically be
the Chef server or any client. It's at this point that you'll make use of the
password you supplied when installing the Chef server. Here, the username/password
are (from the installation instructions earlier on this page),
admin/Escoffier.
http://16.86.192.111:4040
(NOTE THAT, STARTING HERE, NOTES ARE QUICK, ROUGH AND AS YET UNREFINED. PLEASE COME
BACK LATER.)
Knife-up recipes
(Note that existing recipes already used on one client can be ferretted out using
knife. Just find the look-up option for knife.)
These steps happen on any development host, except as noted, but not on the server or any client.
Create a new subdirectory on your development host such as
/home/jack/dev/chef-repos and create a hidden .chef directory. Place a copy of
the knife.rb there. Change the properties to match that host.
Go to the Chef web interface and create a user with admin rights.
(See how to do this.). Copy the private key to a file named
user.pem, e.g.: jack.pem. (Note: if you already had an admin user, and
don't have access to the original PEM, i.e.: if you're inheriting maintenance of the Chef
process, you'll have to re-create it and the original creator becomes invalid.)
Create a cookbooks directory and add any cookbooks.
Use knife commands to up-load the recipe (or recipes) which are Ruby
files.
In the web interface, verify that the cookbook is loaded correctly into the
cookbook section.
Create a role
These steps happen in the web interface and on a chef client (node).
Go to Roles and create a new role. In the menu assign it the cookbook from the
steps above.
Go to the web interface representation of the node being configured and add this
role for it.
Next go to the actual client node and run chef-client again.
Verify that the changes have taken effect.
A client is...
a VM that is a node to Chef
a role
a developer on a development host (see green box in illustration)
To create a developer client, do this:
Open the Chef web interface.
Click the Clients tab.
Click the Create tab.
Fill in the new Name.
Click Admin if appropriate.
Copy (by scraping) and do not lose the private key presented.
Create a PEM file to hold the key, probably on a path like
/home/jack/dev/chef-repos/.chef/jack.pem.
Ensure the PEM file is referenced from knife.rb.*
* This is the knife.rb placed usually on a path like
/home/jack/dev/chef-repos/.chef. The path to the PEM file is
indicated by client_key in knife.rb as shown
here.
Errors
This is the most brittle part of using Chef. You will almost always get:
~/dev/chef-repos/.chef $ knife node list
ERROR: Failed to authenticate to http://16.86.192.111:4000/ as app02 with key /home/jack/dev/chef-repos/.chef/jack.pem
Response: Failed to authenticate. Ensure that your client key is valid.
Hmmmm...
Recipes are managed (or can be) from an independent development host (rather than
the Chef server or a client node).
Recipes are written in Ruby; filenames will end in .rb.
Let's imagine that a recipe already exists and is in use for one or more nodes.
You've just taken over maintenance of your group's Chef installation and you
want to use that recipe for another node that's not using it. To fetch an existing
recipe down to your development host, do this:
Launch a browser and point it at the Chef web interface, e.g.:
http://16.86.192.111:4040
Click the Cookbooks tab, the recipe should be in the list.
Click the version number for the recipe.
Under the recipe name, click the recipes link.
Click on the Ruby file(s) associated with the recipe and scrape or
otherwise save them to the appropriate place in filesystem, e.g.:
/home/jack/dev/chef-repos.
Chef controls nodes through recipes. Chef, when run, likes to create /etc/chef
to do its work.
$ knife configure client ./
—creates a certificate and Ruby file with configuration in it.
Go to http://hostname:4040, username: admin,
password: Escoffier (set in TUI when Chef server installed).
Create a new client "installer" (what's this? "installer" was chosen, but any name
could have been specified).
generates private key that will be used.
replace ____________ in ____________.
Role example: tomcat-role, recipes to configure Tomcat on a node. db-role, recipes to configure, say, MongoDB on a node.
Etc.
To change Tomcat's server.xml, see
cookbook/tomcat/template/default/server.xml.erb, default.rb.