Customizing your Scalarium Cloud using Chef: Writing a Cookbook to set up Redis

Now that we got the Chef basics out of the way, let's start describing how we want the Redis instance to be set up.
First we'll describe some of the default attributes. Here's how the file attributes/default.rb should look like.

There's not much magic here, we're simply configuring a bunch of defaults for the Redis configuration, like the
directory where the data files should be, the port to listen on, and virtual memory size, and so on. We're going to use
these later to set up e.g. Monit, a user to run Redis with and some other things.

Now we're getting to the fun part, writing the recipe to set up the Redis server. Let's go through it step by step. The
file will be recipes/server.rb. Recipes, just like the rest of Chef cookbooks are written in Ruby. There's not much
magic to the code though, it's easy to grasp what it's doing. First, we'll create the user to run Redis with and some
directories.

The code pretty much speaks for itself, which is the great thing about Chef. You can see what's going on without really
knowing much Ruby. We're creating a user based on the attributes defined in our defaults, and we're creating the Redis
data and log directories, both having the user we just created as owner. The directories have been configured in the
attribute defaults above. All attributes set in attribute files and set by Scalarium when the event is triggered, are
available through the node object, simply access them like a nested hash. As a rule of thumb you should make every
value an attribute that is repeated throughout the cookbook, or even used in other cookbooks.

Also note that all these different steps are idempotent in Chef. Running e.g. the user setup twice will not create a
second user. Chef will figure out that the user already exists and simply skip this step.

The steps are easy to follow. We download the Redis package with the version specified in our default attributes. Next
we untar the package and run make. As you can see all we do is run a bunch of Unix commands. In the Chef world, each of these activities is called a resource. Chef brings a bunch of default resources, which are listed on the wiki, but you can easily whip up your own combination of Unix commands, like we're doing here.

We're making good use of Chef's execute resource here, which simply runs the specified command in the specified
directory (notice the cwd set on each of the commands).

When make has run we move the important binaries to /usr/local/bin (the prefix is configured in the default
attributes), and change the binaries to belong to the Redis user. All that's left to do is install a Redis configuration
file and a service script, so let's do that:

We're using of the template resource to create both an init script and the Redis configuration file. Templates are
basically files with placeholders. If you need to make a configuration dynamic, you can simply use whatever's installed
by default as a template, add a couple of placeholders for the values you'd like to have configurable, and then put that
file in the directory templates/default. Let's look at the Redis configuration file for an example.

With the configuration file we basically just set a whole bunch of values derived from the attributes we've configured.
The template resource will take this template, run it through an interpreter, executing the embedded code. The result
will be a neat and fully customized Redis configuration.

We've done the same with the Redis init script, and a Monit configuration, which is not shown detail here. In general we
prefer setting up a Monit configuration for all services we install on our instances, depending on your use case it
could even spare you having to set up a separate init script and let the service be run solely through Monit. You can
find all the templates of this cookbook in our example repository.

Worth mentioning in the recipe snippet above is the service definition in line 8. The Chef service resource abstracts
some of the underlying workings of the system it's running on, so in the case of Scalarium, it's the init system of
Ubuntu 9.10. We define it here so that we can tell it to restart when writing the configuration template. You may wonder
why we're restarting it, as we're setting up a fresh instance. Chef's way of managing infrastructure brings you the most
benefits when your cookbooks are idempotent. That means you can run a cookbook multiple times and it will make sure the resulting system configuration is always the same, and doesn't change anything when nothing needs to be changed.

In the case of the service, the benefit is that you can re-run the recipes at a later point in time, for example to
install a new version of Redis, or to update the configuration. Chef's idempotent way also ensures that files aren't
touched if they haven't changed. So if you're re-running the template resource to generate the configuration file, and
the resulting file isn't different from the configuration file that's already in place, Chef won't touch it, and hence
doesn't restart Redis.

Next step: Configuring Custom Cookbooks

Or go back to Cooking with Chef