Chapter 6. Cookbooks and LWRPs
So, we have learned how to manage different components of our infrastructure using the concept of resources. We also learned what a recipe is and how to handle attributes.
Recipes are nothing but simple Ruby code that defines how the system is going to get to a particular state. A system is comprised of multiple components and each of these components is handled by means of resources.
A resource is a statement of configuration policy. It describes the desired state of an element in our system. It also describes how that state can be achieved. Each resource statement in a Chef recipe corresponds to a specific part of infrastructure: a file, a cron job, a package, a service, and so on.
Recipes group together these resource statements and describe the working configuration of the entire system.
The recipes by themselves aren't good enough to configure a concerned host and we need to manage configuration files, along with packages, services, users, and so on. For this...
While recipes in the world of Chef are a fundamental unit of execution, a cookbook is the fundamental unit of configuration and policy distribution. A cookbook is a container that is responsible for holding everything. It is needed to configure a component of a system, be it the attributes, configuration files, templates, custom resources (more about resources later in this chapter), recipes, versions, metadata, or libraries/helper functions; everything is packed into a cookbook and is used later on during the execution of Chef code when run_list
is expanded during the chef-client run on the concerned machine.
A cookbook has the following directory structure:
The attributes
folder is meant to contain a list of attributes that can be used within the recipes contained...
There are two ways to define custom resources – via LWRPs (lightweight resource providers) or HWRPs (heavyweight resource providers). Before LWRPs were introduced, all extensions to Chef were written using Ruby, and these are referred to as HWRPs. While LWRPs are simple, a HWRP is extremely flexible. The HWRPs reside in the libraries
folder of the cookbook repository. Chef tries to import anything residing there at runtime and is interpreted as code, rather than a Chef DSL. We'll mostly be concerned with LWRPs in this chapter.
A LWRP is meant to extend chef-client so that custom actions can be defined and eventually used in a recipe.
A LWRP has two main components. They are as follows:
One may use existing resources or custom Ruby code to build a new LWRP. Once a LWRP is ready, it's read every time during the chef-client run and processed...
In this chapter, we went through how cookbooks are structured and how to manage recipes stored in a cookbook. We also learned about versioning and its uses. Finally, we went on to create custom resource providers that can help extend the chef-client by providing new resources.
In the next chapter, we'll move into the world of roles and environments and see how we can group together all these cookbooks under a hood to bootstrap machines with a particular role or in a particular environment.