This document describes the pattern for writing Chef cookbooks for hCentive's applications.
As with most software, it is essential to develop Chef cookbooks keeping reusability in mind. Some of the best practices to follow when writing cookbooks are described below.
This pattern is used to construct AMIs for the three types of servers defined in the disaster recovery design document. Cookbooks are defined at three levels - foundation, base and application. The design makes use of the application, library and wrapper cookbook patterns usually referred to as The Berkshelf Way.
The foundation cookbook is run first on a newly provisioned server, followed by base and application cookbooks. A server will be completely setup to run an application only after the foundation, base and application cookbooks are run on it.
A foundation cookbook has recipes to setup a foundation server. These recipes install the set of packages that are required on all servers at hCentive. The cookbook also configures these packages with options specific to hCentive's requirements. For example, ntpd
is installed and configured to synchronize the system clock with hCentive's stratum 2 NTP servers instead of the OS defaults. Similarly, nagios
client is installed and configured to allow NRPE checks from hCentive's nagios servers only. A list of all recipes, and their configurations, is mentioned in the README for the foundation cookbook.
The hcentive-foundation
cookbook has a default
recipe, and recipes specific to ubuntu
and redhat
distribution. The redhat
recipe, for example, will include the yum
recipe for package management, whereas the ubuntu
recipe will include apt
to do the same job.
The base cookbooks are written to setup base servers. They include the foundation cookbook and recipes to install components to setup various base servers for installation of hCentive applications. The cookbooks also include custom configuration to setup these components for hCentive's requirements. An example is a cookbook that sets up a web server to run tomcat applications. This server will have Oracle JDK, Tomcat, Tomcat database connector and Apache web server installed and configured on it. Recipes for components installed with a base cookbook are listed in the README for the cookbook.
The nomenclature for base cookbooks is {server-type}-base
. For example, tomcat7-base
, or jboss-base
.
The application cookbook is a level above the base cookbook. It configures an hCentive product on a server after a Jenkins deployment. It, essentially, implements the configuration guide published by the development team to configure a product. For example, the application cookbook for PHIX web application will depend on the tomcat7-base
cookbook, and have its own recipes to setup context files for various portals. It will also have recipes to update apache configuration to serve static content.
Application cookbooks are named after the application they deploy. Most applications have components that can be deployed separately or together with other components. Each component should have a cookbook of it's own. For example, phix-ui
and phix-webservice
. They should include the name of the base server whenever possible - {application}-{baseserver}
like phix-batchserver
.
As mentioned in the introduction to this page, this design makes use of the library, wrapper and application cookbook patterns. The following section describes the library and wrapper cookbooks.
A library cookbook is an abstract cookbook that defines are set of actions that provide common functionality.
The library cookbook works with a number of concrete providers to implement library functions.
An example is a db
library cookbook that has LWRPs for installing, starting, stopping and backing up databases. The provider (or concrete) cookbooks that use the db
library cookbook are db_postgresql
and db_oracle
cookbooks. These concrete cookbooks implement actual installation, start/stop and backup resources.
A reference implementation can be found in the db
cookbooks by RightScale.
As a practice, original cookbooks, like a community or library cookbook, should not be modified. A wrapper cookbook should be created that modifies the behaviour of the original cookbook by changing default configuration. It will "wrap" the original cookbook with any configuration changes that are made. For example, a wrapper cookbook that sets up openssh
with hardening procedures applied to it. The name of a wrapper cookbook is derived from the cookbook it is wrapping - like hcentive-openssh
.
Just like modifying a community cookbook is not a recommended practice, modifying a shared hCentive cookbooks for a specific project is discouraged. If there is a requirement to modify a shared hCentive cookbook for a project, it is recommended to extend (or wrap) the cookbook.
For instance, there may be a requirement to enable a specific apache module for a project. To do this, create a project specific wrapper cookbook <project>-apache
that depends on the hcentive-apache
cookbook. Then set the ['hcentive']['extra_modules']
attribute with the value of the module you need enabled for the project.
Create a wrapper cookbook
$ berks cookbook phix-apache
Add a dependency for hcentive-apache
cookbook in the cookbook's Berksfile
cookbook "hcentive-apache", git: "https://git.demo.hcentive.com/hcentive-apache"
If required, you can add a version constraint
cookbook "hcentive-apache", "=1.0.0", git: "https://git.demo.hcentive.com/hcentive-apache"
Documentation for more options is available in Berkshelf's documentation.
Add a dependency in the metadata.rb
file
depends "hcentive-apache"
If required, you can add a version constraint
depends "hcentive-apache", "=1.0.0"
In phix-apache
cookbook, create a default attributes file, attributes/default.rb
and override the [hcentive][extra_modules]
attribute. For example, if you want to enable content caching, add mod_headers
to the list
override['hcentive']['extra_modules'] = ['headers']