Workflow is a legacy feature for Chef Automate, which was designed for managing changes to both infrastructure and application code, giving your operations and development teams a common platform for developing, testing, and deploying cookbooks, applications, and more.
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 through 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
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:
- 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. 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.
- 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.
- 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.
- Use the lint.rb recipe to run linting and other static analysis tools against a project’s source code.
- 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
- Use the publish.rb recipe to make any artifact generated by this project available to other phases in the Chef Automate pipeline.
- Use the quality.rb recipe to run additional code quality and reporting tools.
- Use the security.rb recipe to execute security tests against a project’s source code.
- Use the smoke.rb recipe to run smoke tests against deployed build artifacts to ensure they were deployed correctly and are minimally functional.
- 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.
- 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.
The metadata.rb for a build-cookbook is located at
.delivery/build-cookbook/metadata.rb. Update it to include:
This ensures 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:
and then add to the unit.rb recipe:
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
This topic describes the recommended setup for a Chef cookbook project using Chef Automate.
The following example shows how to create a cookbook, with a project and a pipeline, configure it to be built with Chef Automate, and then import 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 (
workspacein 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 --a2-mode
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 statusto verify the change) on the “master” branch:
$ git add .
$ git commit -m 'Initial Commit'
chef generateinitialized a git repository automatically for this cookbook. If you created the build cookbook manually, initialize the git repository with the
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.
- Select the plus sign (+) next to Add a New Project.
- Enter a project name and select a Source Code Provider. Chef Delivery is the default project. (GitHub and Bitbucket are available, but untested)
- After choosing Chef Delivery, select Save and Close to finish adding the project.
chef generate can also create a custom build cookbook for use with
$ 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 'email@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