About the build-cookbook

[edit on GitHub]

Chef Automate uses the chef-client to run recipes for each phase in a build pipeline. The phases are grouped into different stages.

The following illustration shows the phases of each pipeline stage.

The recipes for these phases are run from the build-cookbook. A build-cookbook varies by project type, because projects may use different tools for running unit tests, syntax checks, or lint analysis.

Build Cookbook Structure

A build-cookbook is located in the .delivery directory in a project and defines how the Chef Automate pipeline will build, test, and deploy a project. A build-cookbook should be initially configured to use the delivery-truck cookbook as a dependency in all recipes, after which it may be modified as necessary. The build-cookbook is effectively a wrapper cookbook for the delivery-truck cookbook.

A build node is configured via two isolated chef-client runs: First, the default.rb recipe is run by the chef-client as the root user, after which the phase-specific recipe is run by the chef-client as the build user (dbuild). For example, during the unit phase the first run is the default.rb file, and then the second is the unit.rb file.

The following recipes should be configured to include the corresponding delivery-truck recipe as a dependency:

default.rb
Use the default.rb recipe to configure a project on a build node. This recipe is run by the chef-client as the root user and is a standard default recipe, i.e. the chef-client may use this recipe to configure this project on any node, whether or not it’s part of a Chef Automate pipeline.
deploy.rb
Use the deploy.rb recipe to define how artifacts are published to one (or more) nodes after they are built successfully. The contents of this recipe are project-specific.
functional.rb
Use the functional.rb recipe to run a set functional tests that are specific to this project. The tests are run on a single build node and should target and/or trigger tests against the set of nodes that are updated when this artifact deploys.
lint.rb
Use the lint.rb recipe to run linting and other static analysis tools against a project’s source code.
provision.rb
Use the provision.rb recipe to build any infrastructure that is necessary to run an application. This recipe will discover all metadata.rb and/or metadata.json files that are located in the project’s root directory, plus any cookbook directories located under cookbooks/<project_cookbooks>.
publish.rb
Use the publish.rb recipe to make any artifact generated by this project available to other phases in the Chef Automate pipeline.
quality.rb
Use the quality.rb recipe to run additional code quality and reporting tools.
security.rb
Use the security.rb recipe to execute security tests against a project’s source code.
smoke.rb
Use the smoke.rb recipe to run smoke tests against deployed build artifacts to ensure they were deployed correctly and are minimally functional.
syntax.rb
Use the syntax.rb recipe to verify that changes result in syntactically correct code. This process may involve compiling the code or running a validator for interpreted languages.
unit.rb
Use the unit.rb recipe to run unit tests for the project.

Create Build Cookbook

Pull the delivery-truck and delivery-sugar cookbooks into a build-cookbook. This requires editing the Berksfile, and then updating the metadata.rb file.

Note

This section assumes that Chef Automate is already configured, a project exists, a user may access that project and submit changes, and that all work is being done from that project’s root directory.

Edit the Berksfile

The Berksfile for a build-cookbook is located at .delivery/build-cookbook/Berksfile. Update it to include:

source "https://supermarket.chef.io"

metadata

cookbook 'delivery-truck', github: 'chef-cookbooks/delivery-truck'
cookbook 'delivery-sugar', github: 'chef-cookbooks/delivery-sugar'

This will ensure that the latest versions of the delivery-truck and delivery-sugar cookbooks are pulled into the build-cookbook every time a change is sent to the Chef Automate project pipeline.

Edit metadata.rb

The metadata.rb for a build-cookbook is located at .delivery/build-cookbook/metadata.rb. Update it to include:

depends 'delivery-truck'

This will ensure that the build-cookbook has a dependency on the delivery-truck cookbook.

Add delivery-truck to Recipes

A build-cookbook should define the same phases as the recipes included in the delivery-truck cookbook: default.rb, deploy.rb, functional.rb, lint.rb, provision.rb, publish.rb, quality.rb, security.rb, smoke.rb, syntax.rb, and unit.rb. For example, a build cookbook’s recipe directory should contain an identical list of recipes. For example, run:

$ ls .delivery/build-cookbook/recipes/

the list of recipes should be:

default.rb
deploy.rb
functional.rb
lint.rb
provision.rb
publish.rb
quality.rb
security.rb
smoke.rb
syntax.rb
unit.rb

Each recipe corresponds to a specific phase in the Chef Automate pipeline. The recipes in the build-cookbook should include the same-named recipe in the delivery-truck cookbook. For example, to include the lint.rb recipe from the delivery-truck cookbook, update the lint.rb recipe in the build-cookbook to add the following:

include_recipe 'delivery-truck::lint'

and then add to the unit.rb recipe:

include_recipe 'delivery-truck::unit'

and so on for all of the recipes. This ensures that all of the default behavior for all of the phases for the entire pipeline is available to this build-cookbook.

Set Up Projects

Chef Automate uses projects to organize work across multiple teams. You can create as many projects as you need. A common approach is to have one project for each major component of the system. Each project has its own git repository.

Each project has one (or more) pipelines. Each pipeline has a designated target branch into which it will merge approved changes. Chef Automate uses a “gated master” model that manages merges to the target branch. The typical setup is for each project to have a single pipeline that targets the master branch.

Use the Delivery CLI

Note

These instructions assume that you will use Chef Automate as your source code source of truth and that Chef Automate is not integrated with GitHub Enterprise or GitHub.com.

This topic describes the recommended setup for a Chef cookbook project using Chef Automate.

The following example shows how to create a cookbook, with project and pipeline, configure it to be built with Chef Automate, and then imported it into Chef Automate itself. From your workstation as user with admin privileges on the Chef Automate server, do the following:

  1. Make a working directory (workspace in the example):

    $ mkdir ~/workspace && cd ~/workspace
    
  2. Setup the Delivery CLI to, by default, contact the Chef Automate server at SERVER, with a default ENTERPRISE and ORGANIZATION:

    $ delivery setup --server=SERVER --ent=ENTERPRISE --org=ORGANIZATION --user=USERNAME
    

    Note

    The server, enterprise, organization, and user must already exist.

  3. Create a cookbook:

    $ chef generate cookbook NEW-COOKBOOK-NAME
    
    $ cd NEW-COOKBOOK-NAME
    

    This uses the Chef development kit to generate a new cookbook, including a default recipe and default ChefSpec tests.

  4. Create an initial commit (use git status to verify the change) on the “master” branch:

    $ git add .
    
    $ git commit -m 'Initial Commit'
    

    Running chef generate initialized a git repository automatically for this cookbook. If you created the build cookbook manually, initialize the git repository with the git init command.

  5. Initialize the cookbook for Chef Automate:

    $ delivery init
    

    This creates a new project in Chef Automate, pushes the master branch, creates a feature branch, generates a default Chef Automate project configuration file, pushes the first change for review, and then opens a browser window that shows the change.

  6. Now that you have initialized your project, it is recommended that you integrate the delivery-truck cookbook with your project. Delivery Truck can ensure good build cookbook behavior as well as provide you with recipes already set up to test your project cookbooks and applications.

Use the Web UI

To add a project using the Chef Automate web UI:

  1. Log into the Chef Automate web UI as user with Admin role.

  2. Open the Organizations page and select your organization.

  3. Click the plus sign (+) next to Add a New Project.

  4. Enter a project name and select a Source Code Provider, either Chef Delivery (the default), GitHub, or Bitbucket.

  5. If you choose Chef Delivery, simply click Save and Close to finish adding the project.

  6. If you choose GitHub, a text area opens. Enter the following:

    GitHub Organization Name

    GitHub Project Name

    Pipeline Branch The name of the target branch that Chef Automate will manage (most projects will have master as the target branch). The target branch must exist in the repository.

    Verify SSL When selected, have GitHub perform SSL certificate verification when it connects to Chef Automate to run its web hooks.

  7. If you choose Bitbucket, you must follow the integration steps in Integrate Delivery with Bitbucket before you can add a project. After you have done that you can add a new Chef Automate project through this web UI by entering the Bitbucket project key, repository, and target branch information.

  8. Click Save and Close.

Custom build-cookbook

The pipeline cookbook—pcb—is available on GitHub at https://github.com/chef-cookbooks/pcb. The pcb cookbook is a code generator cookbook that may be used with the chef generate commands packaged in the Chef development kit to generate a build-cookbook for use with a Chef Automate pipeline. The pcb cookbook serves as a complate example of a generated build cookbook, complete with tests, and ready for integration to Chef Automate, while at the same time may be cloned and then customized for your own purposes. This cookbook is not in Chef Supermarket because it is used by the delivery init command, which clones this cookbook to a cached location.

Generate the build-cookbook

The following commands clone the pcb cookbook from GitHub, and then uses the chef generate command to generate a build-cookbook using the pcb cookbook as a template:

$ git clone https://github.com/chef-cookbooks/pcb.git ~/.delivery/cache/generator-cookbooks/pcb

and then:

$ chef generate cookbook .delivery/build-cookbook -g ~/.delivery/cache/generator-cookbooks/pcb