CHAPTER 7

image

Cookbooks

This chapter covers different aspects related to cookbooks.

Cookbooks are the fundamental unit of configuration in chef. Cookbooks determine what gets deployed on the client.

Basics of Cookbooks

A cookbook is the basic unit of configuration and policy definition in chef. It defines a complete scenario for the deployment and configuration of an application.

As an example, a cookbook for Apache or Tomcat would provide all details to install and configure a fully configured Apache or Tomcat server.

A complete cookbook is one that contains all the components required to support the installation and configuration of an application or component.

  • It defines the files that need to be distributed for that component onto the client.
  • It defines the attribute values that should be present on the nodes.
  • It provides definitions for reusability of code.
  • It provides libraries which can be used to extend the functionality of chef.
  • It provides recipes that specify the resources and the order of execution of code on the client.
  • It provides templates for file configurations.
  • It provides metadata which can be used specify any kind of dependency, version constraints, and so on.

We use Ruby as the reference library in chef. For writing specific resources we can use extended DSL (Domain Specific Language).

Let’s discuss the structure and content of a cookbook in detail.

Cookbook Directory Structure

Figure 7-1 shows the typical directory structure of any cookbook.

9781430262954_Fig07-01.jpg

Figure 7-1. Directory structure of a cookbook

The following sections cover all aspects related to the cookbook.

Figure 7-2 shows the working of a cookbook.

9781430262954_Fig07-02.jpg

Figure 7-2. Working of a cookbook

Recipes

Recipes are the configuration units in chef that are actually deployed on the client and are used to configure the system. They are written in Ruby DSL. Recipes are normally a collection of resources with a bit of Ruby code.

A recipe

  • Helps in configuring the nodes.
  • Is stored in a cookbook.
  • Can be used in any other recipe.
  • Is authored in Ruby.
  • Is executed in a top-down approach.

Working with Recipes

In this section we discuss the various approaches that are useful while creating recipes.

Using Data Bags in a Recipe

  • Data bags are a global JSON (JavaScript Object Notification) variable that can store any kind of data but are normally used to store passwords. We can access data bags from the chef server. Chef also indexes them so that they can be easily accessed.
  • The content of a data bag can be used within a recipe. Figure 7-3 shows what the data inside a data bag looks like.

9781430262954_Fig07-03.jpg

Figure 7-3. Contents of a data bag

We can access the created data bag in the recipe using the following syntax:

item = data_bag_item("application", "my_application")

where application is the name of the data bag and my_application is the object name.

We can use a Ruby hash to access data bag items.

item["repository"]  #=> "git://github.com/test/my_application.git"

We can also create a data bag using knife as shown in Figure 7-4.

9781430262954_Fig07-04.jpg

Figure 7-4. Creating a databag

Encrypting Data Bag items

Any item created in a data bag is not encrypted by default, but for creating any sort of secured environment we should encrypt our data bag items. We can achieve the same by creating a secret key. Here we use open SSL to create a secret key.

openssl rand –base64 512 | tr –d '
' > Secret_key

The foregoing command will create a secret key named Secret_key by generating a random number.

Store Keys on Nodes

We can store the encryption key in a file and copy the file to the node that requires it (see Figure 7-5). We need to pass the location of the file inside an attribute.

9781430262954_Fig07-05.jpg

Figure 7-5. Storing keys

The EncryptedDataBagItem.load method expects the secret key as the third argument; we can use EncryptedDataBagItem.load_secret to use the secret file contents and then pass them.

Using Search Results in a Recipe

Chef server maintains an index of your data (environments, nodes, roles). Search index easily allows you to query the data that is indexed and then use it within a recipe.

There is a specified query syntax that supports range, wildcard, exact, and fuzzy.

Search can be done from various places in chef; it can be within a recipe, it can be from the management console.

The search engine in a chef installation is based on Apache Solr.

We can use the result of a search query in a recipe. The following code shows an example of using a simple search query in a recipe:

search(:node, "attribute:value")

The result of a search query can be stored in variable and then can be used anywhere within a recipe.

The search query in Figure 7-6 will return the servers with the role dbserver and then will render the template for all those servers.

9781430262954_Fig07-06.jpg

Figure 7-6. Searching in a recipe

Use Ruby in Recipes

Recipes are written in Ruby, so anything that can be done within Ruby can be done within a recipe. We cover some of the important concepts in the following sections.

Assign a Value to a Variable

We use the ‘=’ operator to assign a value.

The following code shows an example of the ‘=’ operator.

package_name = "apache2"

It will create a variable named package_name with value “apache2”.

Using the Case Statement

We use the case statement when we need to compare an expression and, based upon it, execute certain code.

Figure 7-7 shows a piece of code that demonstrates the use of case statement within a recipe.

9781430262954_Fig07-07.jpg

Figure 7-7. Using case statement

Check for a Condition

We use the ‘if’ expression to check the ‘true or false’ condition in a chef recipe.

Figure 7-8 shows a piece of code that checks if the node platform is Ubuntu or Debian and will execute the code accordingly.

9781430262954_Fig07-08.jpg

Figure 7-8. Checking for a condition

Unless Expression

We use the ‘unless’ expression to execute a piece of code when the result is FALSE.

Figure 7-9 shows an example. If the platform version is anything other than 5.0, then the code will be executed.

9781430262954_Fig07-09.jpg

Figure 7-9. Using ‘unless’ statement

Include Recipes in Recipes

A recipe can be included in any other recipe by using the include_recipe keyword.

The resources of the recipe that is included will be executed in the same order in which they appear in the original recipe. A recipe can be included in another recipe using the following syntax:

include_recipe "apache2::mod_ssl"

We can include a recipe within a recipe any number of times, but it will be processed only for the first time and after that it will be ignored.

Apply Recipes to Run List

If we need to apply any recipe then it needs to be added to the run list using a suitable name which is defined by the cookbook directory structure.

For example, a cookbook might have the following structure:

cookbooks/
        mysql/
                recipes/
                        default.rb
                        server.rb

One is the default recipe which has the same name as that of the cookbook and other recipe is server.rb. Figure 7-10 shows the syntax of a run list.

9781430262954_Fig07-10.jpg

Figure 7-10. Specifying the run list

Exception Handlers and Log Files

We can write the output of a recipe to a log file. This can be achieved using the Chef::Log. There can be various levels of logging which include debug, warn, info, fatal, and error.

The following code can be used to capture some information:

Chef::Log.info('some useful information')

Tags

A tag describes a node in a customized way and then we can group our nodes based on that description.

You can check whether or not your machines have a tag. You can also add or remove tags at any point by using the following command.

tag('mytag')

Tagging can be done using various modes including from knife and from within a recipe. We can use the following code to check whether or not a machine is tagged:

tagged?('mytag')

To return true or false use

tagged?[array of nodes]

We can use the following untag command to remove the tag from any node:

untag('mytag')

See Figure 7-11 for an example.

9781430262954_Fig07-11.jpg

Figure 7-11. Example

The output would be as follows:

[Wed, 12Jul 2014 22:23:45 +0000] INFO: Hey I'm a server
[Wed, 12 Jul 2014 22:23:45 +0000] INFO: I don't have a tag.

Recipe DSL

Recipe DSL is mainly Ruby DSL and we use it to declare resources within a recipe.

We use the methods in the recipe DSL to find out the value of a specific parameter, and then, based on that value, chef takes an action. Anything that can be done with Ruby can be done in a recipe.

We can use attributes, search results, and data bags in the recipe DSL. We can also use the helper methods available. The helper methods are

  • platform?
  • platform_family?
  • value_for_platform
  • value_for_platform_family

Let’s discuss these four helper methods in detail.

Platform?

We use Ohai to detect the value of the node[‘platform’] parameter during every chef run. We use the platform method in a recipe to run platform-specific actions.

We can use the “platform” method in a recipe with the following syntax:

platform?("parameter","parameter")

We can provide one or more than one parameter in a comma-separated list. Typically, we use this method along with conditional Ruby (Case, if, or elseif) (e.g., see Figure 7-12).

9781430262954_Fig07-12.jpg

Figure 7-12. Using platform? method in a recipe

With this method we can create a single cookbook which can be used on multiple operating systems (OSs).

platform_family?

We use the platform_family? method when we want to execute some actions for a specific platform family. We use Ohai to detect the platform_family? attribute. The actions will be executed if one of the listed parameters matched the node['platform_family'].

We can use it in the recipe with the following syntax:

platform_family?("parameter","parameter")

We can provide more than one value of parameters using a comma-separated list.

We also use this method along with conditional Ruby, so that a single cookbook is used on multiple platforms (e.g., see Figure 7-13).

9781430262954_Fig07-13.jpg

Figure 7-13. Using platform_family? method in a recipe

value_for_platform?

We use this method in a recipe with a hash of a particular value based on node['platform'] and node['platform_version']. Ohai provides the value during each chef run.

We can use it in the recipe with the following syntax:

value_for_platform( ["platform"] => { ["version"] => value } )

We can provide one or more than one value for platform in a comma-separated list, and version specifies the version of that platform.

If each value only has a single platform, then the syntax is as shown in Figure 7-14.

9781430262954_Fig07-14.jpg

Figure 7-14. Using value_for_platform? method in a recipe

It there is more than one platform, the syntax will be as shown in Figure 7-15.

9781430262954_Fig07-15.jpg

Figure 7-15. Using value_for_platform? method in a recipe

The code shown in Figure 7-16 will set the value of package_name variable as httpd if that platform is CentOS or Red Hat and Apache2 if platform is Debian or Ubuntu.

9781430262954_Fig07-16.jpg

Figure 7-16. Using value_for_platform? method in a recipe

value_for_platform_family?

We use this method in a recipe with a hash to select value based on node['platform_family'] attribute detected by Ohai.

We can use it in a recipe with the following syntax:

value_for_platform_family({ platform_family => value })

We can provide one or more than one platform_family using a comma-separated list.

If there is a single platform for each value, then the syntax is as shown in Figure 7-17.

9781430262954_Fig07-17.jpg

Figure 7-17. Using value_for_platform_family? method in a recipe

If the value has more than one platform, then the syntax is as shown in Figure 7-18.

9781430262954_Fig07-18.jpg

Figure 7-18. Using value_for_platform_family? method in a recipe

The code shown in Figure 7-19 will set the value of the package variable to httpd-devel if the platform_family is Red Hat or Fedora or Suse and the value would be “apache-dev” if the platform_family is Debian.

9781430262954_Fig07-19.jpg

Figure 7-19. Using value_for_platform_family? method in a recipe

Resources and Providers

Resources are the chunks of Ruby blocks that you declare in your recipe and that actually help in configuring the system. A resource helps us to define the actions that we want our recipe to do. These actions can be anything like installing a package or starting a service. The action is completed with the help of a provider.

During a chef run the resources are identified and mapped to a provider. The provider then executes that action. The resources define the current state of system and the state in which we want the system to be. Providers are used to define the steps to bring the system into that state.

An action is decoupled from the steps required to complete that action, which means that a provider exists for each of the paths that are required to complete the action. This is important because a single action may require different steps, depending on the platform of the system on which the action is being taken.

For example, “install a package” is a single action. To install a package onto various platforms, the steps required for each of those platforms may be different and may require different providers. On a Red Hat or CentOS machine a provider will use the Yum package provider to get the package installed and on a Debian or an Ubuntu machine, a provider will use the APT package installer.

The Chef::Platform class maps providers to platforms (and platform versions).

We use Ohai to get the information about the platform. Based upon that data we can identify the correct provider and then execute the action.

For example, see the resource shown in Figure 7-20.

9781430262954_Fig07-20.jpg

Figure 7-20. Example of a resource

Resources Syntax

A resource has four components.

  • Type
  • Name
  • Attribute (one or more)
  • Action (one or more)

The syntax for a resource is as follows:

type "name" do
        attribute "value"
        action :type_of_action
end

The code in Figure 7-21 can be used to install version 1.16.1 of the tar package.

9781430262954_Fig07-21.jpg

Figure 7-21. Example of a resource used for installing a package

There are predefined actions and attributes for each resource in chef and there is a default value for most of the attributes.

Some attributes are available to all resources; these are sometimes referred to as “meta” attributes and they are commonly used to send notifications to other resources or to set up conditional execution rules.

There is a default value for each action. We need to specify only the nondefault behaviors of actions and attributes.

Attributes associated with resources are not the same as attributes associated with nodes.

Resources

We can use a number of inbuilt chef resources in configuration. We discuss some of the important chef resources here.

Cookbook_file

We use this resource if we want to transfer any file with our cookbook. It transfers the files available in the files/default subdirectory of the cookbook to any specified path. We can use this resource on any platform.

We can use the cookbook_file resource in a recipe as shown in Figure 7-22.

9781430262954_Fig07-22.jpg

Figure 7-22. Using the cookbook_file resource

For example,

cookbook_file "test" do
  path "/root/test"
  action :create
end

This would copy the test file to /root/test.

where

  • cookbook_file is an inbuilt chef resource and it will use Chef::Provider::CookbookFile provider during the chef run.
  • “name” is used to specify the name with which the file will be stored on the node.
  • attribute is used to provide any attributes that are available with this resource.
  • action is the execution that will be done on the node.

The following actions are available with this resource:

  • Create: This is the default action. We use it to create a file.
  • Create_if_missing: We use this action when we need to create a file only when it doesn’t already exist.
  • Delete: We use this action if we want to delete a file.

There are many attributes available with the resource. Some of the important attributes are

  • Backup. We use this attribute to specify the number of backups that should be kept for a file. The default value is 5.
  • Cookbook. We use this attribute to specify the name of the cookbook, if the file is present in some other cookbook.
  • Path. We use this attribute to specify the path of the file.

cron

We use this resource to manage the cron entries. This resource requires access to a crontab program to work properly.

We can use the cron resource can be used in a recipe as shown in Figure 7-23.

9781430262954_Fig07-23.jpg

Figure 7-23. Using the cron resource

For example,

cron "test"do
  hour "3"
  minute "30"
  command "/bin/test"
end        

This would run a program at the specified interval.

where

  • cron is an inbuilt chef resource and it will use the Chef::Provider::Cron provider during the chef run.
  • “name” is used to provide the name with which the cron entry will be created.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The following actions are available in the cron resource:

  • Create: We use this action to create in the crontab file.
  • Delete: We use this action to delete any entry from the crontab file.

Some of the important attributes available with the cron resource are:

  • Day: We use this option to specify the day of the month on which the job should run. The options available are 1–31.
  • Hour: We use this option to specify at which hour (0–23) your job should run. Ute
  • Minute: We use this option to specify the minute (0–59) at which the cron entry should run.
  • Weekday: We use this option to specify the day of the week on which your job should run. The value can vary from 0–6 where 0 = Sunday.

Directory

We use this resource to manage a directory. Chef should have the permission to the directory that will be managed.

We can use the directory resource in a recipe with the syntax shown in Figure 7-24.

9781430262954_Fig07-24.jpg

Figure 7-24. Using the directory resource

where

  • directory is an inbuilt chef resource and it will use the Chef::Provider::Directory provider during the chef run.
  • “name” is used to provide the complete path to the directory.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The following actions are available in the directory resource:

  • Create: We use this action to create any directory.
  • Delete: We use this action to delete any directory.

Some of the important attributes available with this resource are

  • Mode: We use the mode attribute to set the permission of the directory. We need to specify the permissions in octal mode.
  • Owner: We use the owner attribute to specify the user who will be the owner of that directory.
  • Recursive: The value for this attribute can be true or false. We use it to specify whether the directory created or deleted will be done recursively or not.

env

The env resource is a Windows-specific resource and we use it to manage environment variables.

We can use the env resource in a recipe with the syntax shown in Figure 7-25.

9781430262954_Fig07-25.jpg

Figure 7-25. Using the env resource

For example,

env "Test"do
  value "C:\test\test.exe"
end

It would create an environment variable named Test with the provided value.

where

  • env is an inbuilt chef resource and it will use the Chef::Provider::env provider during the chef run.
  • “name” is used to provide the name with which the variable will be created.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The following actions are available in this resource:

  • Create: We use this action if we want to create a new environment variable.
  • Delete: We use this action if we want to delete any environment variable.
  • Modify: We use this action in case we want to edit an environment variable that already exists.

Some of the important attributes available with this resource are

  • Delim: We use this attribute to specify the delimiter that will be used to separate multiple values.
  • Key_name: We use this attribute to specify the name of the key which be managed.
  • Value: We use this attribute to set the value of key_name.

execute

We use the execute resource in case we want to execute a command. Idempotency is not maintained by this resource by default. If we want to maintain the idempotency we need to use the not_if and only_if parameters.

We can use the execute resource in a recipe with the syntax shown in Figure 7-26.

9781430262954_Fig07-26.jpg

Figure 7-26. Using the execute resource

For example,

execute "environment"do
  command "source /etc/environment"
end

This would reload the /etc/environment file.

where

  • execute is an inbuilt chef resource and it will use the Chef::Provider::execute provider during the chef run.
  • “name” is used to provide the name of the command that will run.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The following actions are available with this resource:

  • Run: This is the default action and it indicates that the command should run.
  • Nothing: This action specifies that the command should not run directly but should run only if some other resource specifies it.

Some of the important attributes available with this resource are

  • Command: The command that will be executed.
  • Cwd: We use this option if we want a command to be executed from a certain directory.
  • Environment: We use this option to set the environment variable that will be set before running the commands.
  • Timeout: We use this option to specify the time a command will wait before timing out.
  • User: We use this option to specify the user with which the command should run.

file

We use this resource in case we need to manage the files that are present on a node.

We can use the file resource in a recipe (as shown in Figure 7-27).

9781430262954_Fig07-27.jpg

Figure 7-27. Using the file resource

where

  • file is an inbuilt chef resource and it will use the Chef::Provider::file provider during the chef run.
  • “name” is used to provide the name of the file.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The screenshot in Figure 7-28 shows how we can use the file resource.

9781430262954_Fig07-28.jpg

Figure 7-28. Using the file resource

The following actions are available in the file resource:

  • Create: This is the default action and we use it to create a file.
  • create_if_missing: We use this action in case we want to create a file only if it is not present.
  • Delete: We use this action to delete a file.
  • Touch: We use this action to update the access and the file modification time for a file.

Some of the important attributes available with this resource are

  • Backup: We use this attribute to specify the number of backups that should be kept for a file.
  • Content: We use this attribute to specify the string that will be written to a file.
  • Path: We use this attribute to specify the complete path of the file.

package

We use this resource to manage packages. The resource uses the native functionality of the OS to install the packages on the nodes. Although there are OS-specific chef resources that can be used to manage packages, we recommend using the package resource wherever possible.

We can use the package resource in a recipe with the syntax shown in Figure 7-29

9781430262954_Fig07-29.jpg

Figure 7-29. Using the package resource

where

  • package is an inbuilt chef resource and it will use the Chef::Provider::package provider during the chef run.
  • “name” is used to provide the name of the package.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The following actions are available with the package resource:

  • Install: This is the default action and we use it to install any package.
  • Upgrade: We use this action in case we want to upgrade any package to the latest version.
  • Reconfig: We use this action in case we want to reconfigure any package. There should be a response file for this action.
  • Remove: We use this action in case we want remove any installed package.
  • Purge: We use this action if we want to purge a package. If used, it will remove the package as well as the configuration file related to the package.

Some of the important attributes that are available with this resource are

  • Flush_cache: We use this attribute if we want to flus the yum cache before or after any installation.
  • Package_name: We use this option to specify the name of the package to be installed.
  • Source: This is an optional attribute and we use it to specify the source for providers that use a local file.
  • Version: We use this option if we want to install any specific version of a package.

powershell_script

This is a Windows-specific resource. We use this resource if we want execute a script using powershell. This resource is similar to many chef resources with small tweaks. This resource will create a temporary file rather than running it inline. The commands executed with this resource are not idempotent by default; we can use the not_if and only_if meta parameters to maintain the idempotency.

We can use the powershell_script resource in a recipe with the syntax shown in Figure 7-30.

9781430262954_Fig07-30.jpg

Figure 7-30. Using the powershell_script resource

where

  • powershell_script is an inbuilt chef resource and it will use the Chef::Provider::PowershellScript provider during the chef run.
  • “name” is used to provide the name of the PowerShell Script.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The screenshot in Figure 7-31 shows how to use the powershell_script resource.

9781430262954_Fig07-31.jpg

Figure 7-31. Using the powershell_script resource

The following actions are available in the powershell_script resource:

  • Run: This is the default action. It will run the specified script.
  • Nothing: We use this action if we do not want the resource to be executed directly.

Some of the important attributes available with this resource are

  • Code: We use the attribute to specify the set of commands to be executed.
  • Command: We use this attribute to specify the name of the command to execute.
  • Flags: We use this option to pass the command line flags.

remote_file

We use this resource if we want to transfer a file from a remote location to the node. The functioning of this resource is similar to that of the file resource.

We can use it in a recipe with the syntax shown in Figure 7-32

9781430262954_Fig07-32.jpg

Figure 7-32. Using the remote_file resource

where

  • remote_file is an inbuilt chef resource and it will use the Chef::Provider::RemoteFile provider during the chef run.
  • “name” is used to provide the name and location of the remote file.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The screenshot in Figure 7-33 shows how we can use this resource in a recipe.

9781430262954_Fig07-33.jpg

Figure 7-33. Using the remote_file resource

The following actions are available in the remote_file resource:

  • Create: We use this action to download the file from the remote source to the node.
  • Create_if_missing: We also use it to download the file from the remote source to the node but only if the file is missing.

Some of the important attributes available with this resource are

  • Backup: We use this attribute to specify the number of backups that should be kept for the file.
  • Checksum: This is an optional setting and we use it if we don’t need the file to be downloaded again. It will check the checksum.
  • Source: We use this attribute to specify the source from which the file should be downloaded.

script

We use this resource to execute the scripts. We can choose the interpreter we want to use. It creates a temporary file and executes the file rather than running it inline.

The commands that are executed by this resource are not idempotent by nature; to maintain idempotency we need to use the not_if and only_if meta parameters.

We can use script in a recipe with the syntax shown in Figure 7-34

9781430262954_Fig07-34.jpg

Figure 7-34. Using the script resource

where

  • script is an inbuilt chef resource and it will use the Chef::Provider::Script provider during the chef run.
  • “name” is used to provide the name with which the script will run.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The following actions are available with this resource:

  • Run: This is the default action and it indicates that the command should run.
  • Nothing: This action specifies that the command should not run directly but should run only if some other resource specifies it.

Some of the important attributes available with this resource are

  • Command: The command that will be executed.
  • Cwd: We use this option if we want a command to be executed from a certain directory.
  • Environment: We use this option to set the environment variable that will be set before running the commands.
  • Timeout: We use this option to specify the time a command will wait before timing out.
  • User: We use this option to specify the user with which the command should run.

service

We use this resource to manage any service on a node.

The syntax for using the service resource in a recipe is shown in Figure 7-35.

9781430262954_Fig07-35.jpg

Figure 7-35. Using the service resource

where

  • service is an inbuilt chef resource and it will use the provider based on the OS of the node.
  • “name” is used to provide the name of the service.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

The following actions are available with this resource:

  • Enable: We use this action if we want to enable a service on startup.
  • Disable: We use this action to disable a service.
  • Start: We use this action to start a service.
  • Stop: We use this action to stop a service.
  • Restart: We use this action to restart a service.
  • Reload: We use this action to reload the configuration files for a service.

Some of the important attributes available with this resource are

  • Reload_commmand: The command that will be used to reload the service.
  • Restart_command: The command that will be used to restart the service.
  • Service_name: The name of the service that will be managed.
  • Start_command: The command that will be used to start the service.
  • Stop_command: The command that will be used to stop the service.

Template

We use this resource if we want to manage the contents of a file. It stores files in an erb (Embedded Ruby) template. We normally store templates in the template/default available in the cookbook subdirectory.

We can use the template resource in the recipe as shown in Figure 7-36.

9781430262954_Fig07-36.jpg

Figure 7-36. Using the template resource

For example,

template "/etc/nginx.conf"do
  source "nginx.conf.erb"
end

We use this resource to configure a file from a template

where

  • template is an inbuilt chef resource and it will use the Chef::Provider::Template provider during the chef run.
  • “name” is used to provide the name of the template file.
  • attribute is used to provide one or more attributes that the resource will use.
  • action is the actual execution that will be done on the node.

Following are the actions that are available with this resource:

  • Create: This is the default action and we use it to create a file.
  • Create_if_missing: This action will create a file if the file doesn’t exist.

Some of the important attributes available with this resource are

  • Backup: We use this option to specify the number of backups that should be kept for a file.
  • Path: We use this attribute to provide the complete path to the file.
  • Source: We use this option to specify the location of the source file.
  • Variable: We use this option to provide variables in the template file.

Attributes Files

Attribute are used to override the settings on any node. During each chef run, the attributes on a node are compared to those in the cookbook and then, depending upon the precedence level, the settings are done.

The attribute file is located in the attributes subdirectory of the cookbook. During each chef run, the attributes in the attributes files are evaluated against the node object.

For example, the mysql cookbook contains the following attribute file (called default.rb):

default["mysql"]["data_dir"]          = "/opt/local/lib/mysql"
default["mysql"]["port"] = ""3306"

The use of the node object is implicit here. The following example is equivalent to the previous one:

node.default["mysql"]["data_dir"]          = "/etc/apache2"
node.default["mysql"]["port"] = '3306'

Chef server keeps the attributes indexed so that they are easy to access.

Attributes Types

The following types of attributes are available:

  • Default
  • Force_default
  • Force_override
  • Normal
  • Override
  • Automatic

Attributes Methods

Various attribute methods can be used in the attribute files of the cookbook or directly in a recipe. The various attribute methods that are available are

  • Override
  • Default
  • Normal

There is one more method, attribute?, that is available and is used to check the value of an attribute.

We can use the attribute?() method  in an attributes file as shown in Figure 7-37.

9781430262954_Fig07-37.jpg

Figure 7-37. Using attributes

Similarly, we can use it in a recipe as shown in Figure 7-38.

9781430262954_Fig07-38.jpg

Figure 7-38. Using attributes in recipes

Precedence

During a chef run, saved attributes are retrieved from the chef server and are merged with the attributes on the local system. The attribute type and the source of the attribute determine which attribute values have priority over others.

In general, use the default attributes as much as possible (or even all the time).

The merge order for attribute precedence will do most of the work, yet leaving many levels of precedence available for the situations in which they are truly necessary.

Attribute values are applied in the following order (from low to high priority): 1 being the lowest and 15 being the highest.

9781430262954_unFig07-01.jpg

In other words, an automatic attribute takes precedence over a forced override attribute, a forced override attribute takes precedence over an override attribute, an override attribute takes precedence over a normal attribute, and so on.

Definitions

Definitions are used to create new resources by combing the existing resources. Usually we use definitions when we are repeating a pattern of resources. Definition is not a resource or a lightweight resource but is actually a collection of two or more resource declarations.

There is a separate directory where we create definitions.

A definition is never declared into a cookbook.

There are mainly three components of a definition.

  • The name of the resource.
  • The arguments (one or more than one) that will be used to set the value for the parameters.
  • A hash that would be used to accessing parameters and their values.

If we do not set any value for a parameter, we use the default value.

The syntax of a definition is as shown in Figure 7-39.

9781430262954_Fig07-39.jpg

Figure 7-39. Using definitions

Figure 7-40 shows an example of a definition with name apache_site with ‘action’ as a parameter and ‘enable’ as its argument.  

9781430262954_Fig07-40.jpg

Figure 7-40. Using definitions

Libraries

A library is a way to increase chef functionality. We can implement a Ruby class directly and then use it in our recipe. There is a separate directory for library where we create libraries. A library once defined is available to be used anywhere in the cookbook.

The basic syntax of a library is shown in Figure 7-41.

9781430262954_Fig07-41.jpg

Figure 7-41. Defining libraries

This syntax can be used in a recipe with the code shown in Figure 7-42.

9781430262954_Fig07-42.jpg

Figure 7-42. Using libraries

For example, we could create a simple library that extends Chef::Recipe::, as shown in Figure 7-43.

9781430262954_Fig07-43.jpg

Figure 7-43. Creating a library

We can use this library in a recipe as shown in Figure 7-44.

9781430262954_Fig07-44.jpg

Figure 7-44. Using Library in recipe

Metadata

We use metadata to store certain information about the cookbook. We use the file metadata.rb to provide this information. The file is located in the cookbook directory.

The following things can be specified in the cookbook. Figure 7-45 shows the metadata file of the build-essential cookbook.

9781430262954_Fig07-45.jpg

Figure 7-45. Metadata

A metadata can be used to specify the following important things:

  • Dependencies: If the cookbook is dependent on any other cookbook.
  • Description: What is the cookbook actually doing.
  • Supported OS list.
  • Name of the cookbook.
  • Version of the cookbook.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset