Chef Best practices
This article is the II part covering Chef. Please refer to Automation, Provisioning & Configuration Management (CHEF) for an introduction.
As a matter of fact, Chef is truly an astounding tool. It keeps the cooking metaphor actively going.
Following is the list of best practices that I would like to cover in the article:
- Project creation and “readme driven development”
- A sane build system with Rake
- Continuous integration with Travis
- TDD with Chefspec
- Workflow with Spork
- Verification with Minitest
Getting Started:
1). First and prime important step is to create a new Project. In this section everything should be source controlled. Here in the example a Github repo has been created for all the codes and for the verification or to see step to step process of the development as well as mistakes, they can be easily viewed from the commit history. Follow all the steps and do same for your project:
git init
Second objective is to perform a Source Code Management. By running the following command you can make use of git flow to manage your features by selecting all the default settings and if you aren’t using it, then its time you should start working on it.
git flow init
Using Readme Driven Development is top best practice that can be started by README.md file. This practice is really important as it helps you to focus your mind and cause you think like a user.
Here Rake is being used for an already build system. Following is the list of tasks that are to be considered:
- Rake check: This is responsible for checking all other dependencies.
- Rake build: The main aim of rake build is to manage and run the test suites.
- Rake start: It acts as an envelope for vagrant up.
2). Another best practice is to Set up a Ruby version for the project. This is done by creating two version files: .rvmrc and .rbenv.
After Ruby files have been created, next step is to create a Gemfile. The main aim of creating this file is to set up all the project dependencies.
Below is the example with the commands that will help you in creating a Gemfile:
source "http://rubygems.org"
ruby ‘1.9.3’
gem ‘rake’, ‘10.0.4’
After creation, installation of these dependencies is the essential key step which is possible with below mentioned instruction:
bundle install
Creating a new Rakefile is also necessary. It contains a placeholder task per those that have already been defined in our Readme file.
By making use of Rake for setting up a build system helps in automating some common tasks.
3). Continuous Integration with Travis is another elite practice.
But before we proceed further, it’s important to create a link between the repository and the Travis. It is an essential step in the cases where users have already created a repository for the code as part of the series.
After link is made, you can configure Travis by creating a new Travis file i.e; .travis.yml in the root of the project directory.
Configuring Travis helps in eliminating development gem dependencies so as to pace things up and tests on the CI server. Furthermore, it also tests the master as well as the development branches.
Updating your Gemfile is also important in order to ensure that any future development related Gems are correctly excluded. Add this to your Gemfile:
group :development do
end
After Travis is configured, you can update your README.md by adding the Travis notifications to indicate the status of the build.
4). Another best practice is to perform TDD using Chefspec to “spec” out the cookbook.
First step is to add chefspec to your Gemfile by updating the file and by all means also do bundle update.
After updating is done you can Automate Chefspec Cookbook Creation. As per the Chefspec documentation, you are capable of creating a cookbook and on the other hand use another command to create the spec directory.
According to user or your varying needs you may even wish to create a new_cookbook.
For example: To build up a new rake task: new_cookbook below are the instructions to be followed
desc "Creates a new cookbook."
task :new_cookbook, :name do |t, args| sh "bundle exec knife cookbook create #{args.name}" sh "bundle exec knife cookbook create_specs #{args.name}" end
As soon as you generate new cookbook you can also create your sample Cookbook
rake new_cookbook motd
At this point you have a new blank cookbook and can run the basic tests with rspec cookbooks. You can even add a rake task and upgrade the build tasks for the usage. At last you can add the spec for the motd cookbook in the motd/spec/default_spec.rb file by creating a Failing Spec. By executing the rake, build should be able to show “this now fails”. Thereafter you are required to implement the cookbook.
Make your Spec Pass and the templates/default/motd.tail.erb file:
Finally test driven cookbook is made and as Travis file is already referencing the build tasks, when we push this code up, CI will run this test and verify your work.
5).Working with Spork is another practice in Chef. This tool helps in collaborative cookbook development. It also helps single developer to control and place things in order when it comes to bumping versions.
So to test this out, initially we will install knife-spork and will do a small edit to your motd cookbook to use its features. First step is to always update your Gemfile by adding the spork gem to the Gemfile. This is not required by the CI server and is put under the development block:
Following example exemplify the instruction:
group :development do
gem "knife-spork", "~> 1.0.17" end
After updating, next step is to configure your Spork by creating a config/spork-config.yml file to put in the default configuration. Though there is a little issue of having lots of configurations in various places and is consolidated over a period of time.
Configure your Spork using following instructions:
mkdir config
touch spork-config.yml
Running the rake build task shows that our test has failed and can be set right just by updating the template. The moment you complete your updates and the test pass, we should bump the version number of the cookbook by bundle exec knife spork bump motd patch. And finally you will make use of the upload feature so as to upload it to the chef server “freezing” it at the same time.
Another great feature of spork is the spork promote command that allows you to constrain a specific version of a cookbook to a specific environment. A use case could be:
- Cookbook 2.0 is being verified on your development environment.
- Cookbook 1.9 is in production environment.
- When things looks good can be rolled out to production.
6). Last but not the least is to set up the mini test suite to verify your cookbooks on a real server. This is done by placing your files in the right place and adding default to your existing cookbook:
mkdir -p cookbooks/motd/files/default/tests/minitest
touch cookbooks/motd/files/default/tests/minitest/default_test.rb
There is also another option available with you in order to avoid the above mentioned action. You can simply modify the new_cookbook rake task to make this part of the cookbook buildout. Last stage comes with deploying the Cookbook and testing it. This helps you in building up a cookbooks that actually works when used on the servers. They also act as a safety net as they run whenever the server is provisioned.
Conclusion:
Above mentioned are the best practices of Chef that will help you in building cookbooks in a true, test-driven way. Implementing all these will help in saving you from all key headaches by keeping your custom cookbook changes in new cookbooks and without problems be able to create targeted pull requests to share back with the community.
I expect you’ll be smart enough to take away some good practices here.
Happy Chefing!