A Simple Node Definition - Reliably Deploying Rails Applications: Hassle free provisioning, reliable deployment (2014)

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

5.2 - A Simple Node Definition

Overview

A node refers to a single server (for example a single VPS we’re provisioning). In this section we’ll look at what goes into a node definition file and create a simple one to be used in our example redis project.

A redis node

Create a file example-redis-server.json in the nodes directory and enter the following:

1 {

2 "redis": {

3 "dont_bind" : true

4 },

5 "run_list":

6 [

7 "role[redis-server]"

8 ]

9 }

We can see this is standard JSON object with two key sections. We’ll begin by looking a the “run_list” section.

Run List

In chef a run_list is an array of roles or recipes to be applied to (installed on) a node. Chef will work through the recipes and roles in the order they are listed and apply them. As we’ll see in the next chapter, a role definition is in practice a “mini node definition” which looks almost identical to the above.

A run list can contain a list of roles and recipes, a role is identified in the following format:

1 role[role_name]

and a recipe by:

1 recipe[recipe_name]

Although roles and recipes can be specified just by name, it’s good practice to always specify whether it’s a role or a recipe to avoid unexpected results if there are roles and recipes with the same name.

In this case we only want to apply a single role “redis-server” but in practice there would usually be several roles here.

For example there might be “xyz-company-server” role which applies all of the common attributes a particular companies servers have.

I’ve often used this for clients who have a standard base package set, security setup and look and feel which they apply to every single one of their servers.

Customising Recipes with Attributes

As per section 5.1, attributes can be used to customise the behavior of cookbooks.

The first section of the node definition looks like this:

1 {

2 "redis": {

3 "dont_bind" : true

4 }

5 ....

The above section defines the “attributes” of the node. These attributes are accessible by individual recipes to customise their execution.

So in this scenario, the value of node[:redis]['dont_bind'] would be overridden from the default (false) defined in the cookbooks attributes/default.rb file to our new value, true.

We could expand the functionality of this cookbook to be even more granular, for example we could modify the redis.conf.erb file to look like this:

1 <% if node[:redis] %>

2 <% if (interface = node[:redis][:interface])

3 bind <%= interface %>

4 <% else %>

5 bind 127.0.0.1

6 <% end %>

7 <% else %>

8 bind 127.0.0.1

9 <% end %>

with the first section of our node definition looking like this:

1 {

2 "redis": {

3 "interface" : 127.0.0.1

4 }

5 ....

This would, as before, check that the redis key exists and if so look for the subkey “interface.” If the interface key is defined, it would add a line to bind redis to that interface (in the above example 127.0.0.1). Otherwise it will always default to binding to 127.0.0.1 (the default loopback interface).

Now we can really see the power of chef. A recipe can be used to automate any combination of commands and file changes we need to make on a server we set up. Any aspect of the setup which varies between nodes can be customised using attributes.

All attributes relating to a particular node are stored in one place so we can easily see exactly how any single node is set to be configured.

Naming Node Definitions

We’ll cover generating and naming node definition files in detail in section 5.4.

In brief node definitions should be stored in the nodes folder and named according to the hostname you would use to connect to them. So for example if you would use ssh root@my_shiny_server.co.uk to ssh into the server you’re provisioning, the node definition file should be calledmy_shiny_server.co.uk.json.

This will make your life significantly easier as the number of node definitions grows both for organisation and because it will allow knife solo to automatically select the file based on hostname.