About the build-cookbook¶
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 allmetadata.rb
and/ormetadata.json
files that are located in the project’s root directory, plus any cookbook directories located undercookbooks/<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:
Make a working directory (
workspace
in the example):$ mkdir ~/workspace && cd ~/workspace
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.
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.
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 thegit init
command.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.
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:
Log into the Chef Automate web UI as user with Admin role.
Open the Organizations page and select your organization.
Click the plus sign (+) next to Add a New Project.
Enter a project name and select a Source Code Provider, either Chef Delivery (the default), GitHub, or Bitbucket.
If you choose Chef Delivery, simply click Save and Close to finish adding the project.
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.
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.
Click Save and Close.
Custom build-cookbook¶
chef generate
can also create a custom build cookbook for use with Delivery:
$ chef generate build-cookbook NAME [options]
The following options are available with chef generate build-cookbook
:
-C, --copyright COPYRIGHT Name of the copyright holder - defaults to 'The Authors'
-m, --email EMAIL Email address of the author - defaults to 'you@example.com'
-a, --generator-arg KEY=VALUE Use to set arbitrary attribute KEY to VALUE in the code_generator cookbook
-h, --help Show this message
-I, --license LICENSE all_rights, apachev2, mit, gplv2, gplv3 - defaults to all_rights
-v, --version Show chef version
-g GENERATOR_COOKBOOK_PATH, Use GENERATOR_COOKBOOK_PATH for the code_generator cookbook
--generator-cookbook