Chef:Powerful Infrastructure Automation
上QQ阅读APP看书,第一时间看更新

Chapter 4. Working with Cookbooks

Cookbooks are one of the fundamental components of the Chef system. They are containers for recipes, providers, resources, templates, and all the logic and information required to manage your infrastructure. This chapter covers the following:

  • Organization of cookbooks
  • Building cookbooks
  • Developing recipes
  • Handling multiple platforms for a cookbook organization

Cookbooks are one of the core components of Chef. They are, as their name suggests, a collection of recipes and other data that when combined provide a specific set of functionality to a system administrator. In each cookbook, you will find a collection of directories and files that describe the cookbook and its recipes and functionality. The core components of a cookbook are as follows:

  • Cookbook metadata
  • Attributes
  • Recipes
  • Templates
  • Definitions
  • Resources
  • Providers
  • Ruby libraries
  • Support files

A cookbook is a collection of files and directories with a well-known structure. Not every cookbook has all of these components. For example, there may be no need to develop custom resources or providers in a cookbook that only uses Chef-supplied resources. However, every cookbook does need to have a metadata file that provides various bits of information such as its name, version, dependencies, and supported systems.

Let's take a look at the memcached cookbook as it is a reasonably simple cookbook that is capable of installing and configuring the memcache server, which is a distributed memory-backed cache service:

Working with Cookbooks

Here, you can see that this cookbook contains attributes, definitions, recipes, and templates, as well as a file named metadata.rb (the metadata file) and a README.md file. It is a good idea to provide examples of how to use your cookbook and recipes in some sort of documentation, such as a README.md file. When you look at the preceding screenshot, you will see that the directory names map to the component names and each contains some files or subdirectories with files. We will discuss the organization of the specific Chef components in greater detail further on as we dive into more details on each type later. For now, it is sufficient to know that the directory structure is designed to group together files for each type of component. Also notice that, as mentioned earlier, this cookbook is an example of one that does not have all the components, as there are no new resources or providers in this cookbook.

Some of these files are purely informational and have no effect on your recipes or Chef itself, such as the README.md file. This file, and others such as CHANGELOG, LICENSE, or DEVELOPMENT files, is included to convey information to you about how to participate, license, or otherwise use the cookbook.

There is a lot of information that is stored inside a cookbook—this information includes the steps to take in order to achieve a desired effect such as the installation of a service or provisioning of users on a host. A high-level overview of the content that we will be learning about in this chapter, so that you have an idea of how the components work together before you learn about them in depth, is shown as follows:

  • Attributes: These are attributes that the cookbook's recipes rely on. A well-defined cookbook should contain some sane defaults for the recipes such as installation directories, usernames, downloadable URLs, and version numbers. Anything a recipe expects the node to have defined should be given a default value so that the recipe will behave as expected.
  • Recipes: Ruby scripts define the recipes in the cookbook. A cookbook can contain as few as one or as many recipes as its author would like to put into it. Most package-specific cookbooks only contain a few recipes, while some cookbooks, such as your organization's private cookbook, may have dozens of recipes for internal use.
  • Templates: These are Ruby ERB files that are used to describe any file that needs to have some dynamic data in it; often, these are used for startup scripts or configuration files.
  • Resources: These describe a resource that can be used in a recipe. Resources are Ruby scripts that use Chef's resource domain-specific language (DSL) to describe various actions, attributes, and other properties of the resource.
  • Providers: These describe an implementation of a resource; in the case of the supervisord cookbook, the service provider file outlines the actual implementation-specific logic of the actions that a resource can perform. There are many types of services that you could have: supervisord, runit, monit, bluepill, and so on.

Additionally, cookbooks may include a variety of support files that are not directly part of the recipes, such as the following:

  • Definitions: These are used to build reusable templates for resources. Perhaps you want to define the structure of a user account, a background worker, or a runnable process. These are a way to programmatically describe what these look like and implement any logic they might need.
  • Ruby libraries: Any reusable code that your recipes need can be included in the cookbook. Things that go in here are accessible by your recipes and automatically loaded for you.
  • Support Files: These are arbitrary data files that don't fall into any of the other categories.
  • Tests: Recipes, composed of Ruby code, can include unit tests or cucumber tests to verify that the logic works. Note that these tests are unit tests, not integration tests; they are not designed to ensure that you have configured your nodes properly or that there are no conflicts or other issues when applying these recipes.