A simple chef role - Reliably Deploying Rails Applications: Hassle free provisioning, reliable deployment (2014)

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

5.3 - A simple chef role

Overview

Roles define the components required for a server to fulfill a particular role. In this example we’ll be defining a simple Redis Server role, which will use the Redis cookbook and recipe from sections 5.1 and 5.2.

Creating a role definition

The below shows the JSON for our Redis role stored in roles/redis-server.json:

1 {

2 "name": "redis-server",

3 "description": "Redis server",

4 "default_attributes": {

5 "redis": {

6 "dont_bind" : false

7 }

8 },

9 "json_class": "Chef::Role",

10 "run_list": [

11 "monit-tlq",

12 "redis-tlq",

13 "monit_configs-tlq::redis-server"

14 ],

15 "chef_type": "role"

16 }

We can see that this is very similar to our node definition from the previous chapter.

We begin by specifying the name of the recipe (redis-server) and a simple human readable description of what the role does. When chef encounters the line role[redis-server] in the nodes run list, it will look for roles with the “name” attribute set to “redis-server.” It will look for these role definitions in the json files in the folder specified as role_path in knife.rb.

Default Attributes

Default attributes allow us to specify what value an attribute should have if no value is specified in the node definition file.

For example referring back to our earlier redis-server recipe, if it is our preference that our Redis servers never bind to 127.0.0.1, we could have the following default attributes section in redis-server.json:

1 "default_attributes": {

2 redis: {

3 "dont_bind" : true

4 }

5 },

6 ....

In this scenario if our node definition doesn’t specify a value for the don't_bind key, it will default to true. I’d strongly recommend against this default configuration as it makes your Redis server insecure by default without proper firewall configuration however it serves to demonstrate the principal.

json_class and chef_type

These specify the type of definition this file provides. This is important to differentiate between roles and recipes, particularly if you have roles and recipes with the same names.

run_list

As in our node definition, this is an array which can contain a list of recipes or indeed other roles which should be applied to a node which has this role.

Here we see the recipe[recipe_name] syntax as before, we also see the syntax for defining a particular recipe within a cookbook:

1 "recipe[monit_configs-tlq::redis-server]"

This tells us that there is a cookbook called monit_configs which contains a recipe redis-server which we should install. When we specify a recipe without the :: part the default recipe is installed. So writing:

1 recipe[my_great_recipe]

is equivalent to:

1 recipe[my_great_recipe::default]

You can see that this role uses two new cookbooks, monit_configs-tlq and monit-tlq. We’ll download and add those to site-cookbooks in the next chapter.

Now we’ve got a reasonable understanding of how to construct a simple chef repository with basic role definitions and recipes, we’ll move onto applying our simple node definition to a VPS.