In my last post, we covered setting up the basic install of the Chef Server, the Chef client, and a test node that we bootstrapped with Chef. Now let’s talk about some of the basics and hopefully by the end of this post we’ll get to see Chef in action! Let’s start off by talking about some of the basic constructs with Chef…
Cookbooks
Cookbooks can be seen as the fundamental configuration item in Chef. Cookbooks are used to configure a specific item. for instance, you might have a cookbook that’s called ‘mysql’ that’s used to install and configure a MySQL server on a host. There might be another cookbook called ‘httpd’ that installs and configures the Apache web server on a host. Cookbooks are created on the Chef client and then uploaded and stored on the Chef server. As we’ll see going forward, we don’t actually spend much time working directly on the Chef server. Rather, we work on the Chef client and then upload our work to the server for consumption by Chef nodes.
Recipes
Recipes are the main building block of cookbooks. Cookbooks can contain the recipes themselves, or they can be dependant on other recipes that exist outside of the particular cookbook. A recipe is composed of different resources. Chef defines a resource as a statement of configuration policy. For instance, a resource may be a file that you want to set particular attributes on. Or a particular package and how you want it to be installed on the system. When a run list executes a recipe, it verifies each resource is in the prescribed state. If it is, it passes to the next resource, if it isn’t, it attempts to remediate it to the prescribed state.
Run lists
Once you’ve created a cookbook and wish to deploy it to a host, you need a means to bind the cookbook to the host. This is done by assigning the cookbook to the nodes ‘run list’. A run list is simply a list of cookbooks that are associated with a given node. When the Chef node checks in with the server it executes it’s run list. A node is said to be ‘ in policy’ once the run list has completed successfully.
Are you entirely lost yet? If you’re like me, this stuff will start clicking once we get into the config. So let’s start off with a basic configuration for a web server on our test node.
The first thing we need to do is create a cookbook, this is done by using the following command on the client…
knife cookbook create
So let’s run that on our client…
As you can see the cookbook was created successfully. Let’s dig into the cookbook and see what it created by default…
If we browse into our chef-repo directory, then cookbooks, we should see the cookbook we created. Digging further into that file we should see a recipes folder that has a single file in it called ‘default.rb’. Let’s open that in a text editor and see what’s there…
To start with, all we should have is a comments section at the top. This is the default recipe file for our new cookbook called webserver. So let’s have this recipe install the Apache web server, enable the service, and start the service. This is done with these commands…
Now exit and save the cookbook. Now that we have the cookbook created locally on the client, we need to upload it to the server. We can upload a single cookbook or all of them.
knife cookbook upload
Let’s see both methods…
So we can either pass the name of the cookbook we want to upload, or the ‘-a’ flag to tell it to upload all of the cookbooks. Once it’s uploaded on the server, all we have to do is edit the nodes run list to contain the webserver cookbook. This is done with the following command…
knife node edit
The first time I ran the command I got this message…
So I had to set the editor value with this command…
export "EDITOR=vim"
Once I did that editing the node gave me the default node file which looked like this…
Now all you have to do is add your new cookbook to the nodes run list…
Once you do that, save and quit. Now let’s hop over to our Chef test node and see if any of this works. In order for the Chef client to check in, the application ‘chef-client’ must be run. We’ll talk in a future post on how to automate this on the node, but for now, let’s just run it manually…
As you can see, the chef-client pulls the nodes run list and runs the associated cookbooks. You can see in the log where it installed httpd, enables the service, and then starts the service. Let’s see if it worked!
Sure enough! Apache is now installed and running on our test node! Let’s take this a step further and use Chef to give the server a new index page. Let’s start by putting the files we want to use in webserver cookbook. Browse into the cookbook and you should see a files directory…
As you can see, within the files directory is another folder called ‘default’. That’s where I’ve uploaded our new index.html and a jpg that I’m using in the HTML. Once this is done, all we need to do is edit the default recipe…
Now all we have to do is tell the recipe to copy the files, that’s done with two cookbook_file definitions…
Now that we’re done doing updates we need to upload the cookbooks to the Chef server again…
Pretty easy right? We’re just telling the node which files to copy and where to put them. Let’s rerun the chef-client on the node and see what happens…
Note how the chef-client checks to make sure that the Apache service is installed, enabled, and running. It sees that this is up to date and moves onto the files which it copies into the correct file locations…
Once it’s done, let’s check and see what we get when we browse to our node…
And there you have it! You can see how powerful this can be when managing multiple nodes that need the same or similar configuration. In the next post, we’ll talk about how to use roles as well as multiple and dependent recipes.