The files in this gist are for having Jenkins automatically manage a chef repository using git submodules. This allows for clean, clutter free management of individual cookbooks, and individual respositories for roles, environments and data bags in our chef-repo
.
The process relies on using Github (we use Github Enterprise) and Jenkins in combination with the Jenkins Github plugin to notify Jenkins when a repository has changed.
Our chef-repo
directory looks something like:
chef-repo
- cookbooks
- Each cookbook is a git submodule managed by Jenkins
- data_bags (git submodule managed by Jenkins)
- environments (git submodule managed by Jenkins)
- roles (git submodule managed by Jenkins)
- All other normal files and directories
So that we can use git submodules for dependency cookbooks that are maintained by a third parties, there is a dependencies.json
file placed in the root of each cookbook. See 0-dependencies.json
and 0-dependencies-json-notes.md
.
Each cookbook has a Jenkins job that recives a Github callback when changes are pushed into it. These jobs all have two build steps:
- 1-cookbook-update.sh
- 2-cookbook-dependency.py
- 3-chef-repo-push.sh
1-cookbook-update.sh
updates the chef repo for the updated cookbook, while 2-cookbook-dependency.py
adds or updates cookbook dependencies. Note that at this time these scripts do not do conflict resolution for different versions or repositories of the same dependency across cookbooks. 3-chef-repo-push.sh
pushes the submodule updates back to Github.
4-other-build.sh
is used for each respository that contains the roles, environments, and data bags. Roles, environments and data bags each have a Jenkins job which like the cookbooks will update the submodule reference in the chef-repo
repository.
When chef-repo
is updated, Github makes a callback to Jenkins which triggers a job to upload changes to the Chef server. All of the scripts use a uniform commit message style to chef-repo so that the 5-knife_production_upload.sh
script can extract the proper type of update to run and what cookbook(s) to update.
If you want to make sure that cookbooks pass tests prior to inclusion, tt should be trivial to add build-steps in Jenkins that execute unit tests or other acceptance testing prior to making the commits to chef-repo.