Using Travis CI to make sure your Chef repo and server are in sync

Greg Karékinian ·

Here’s the first post by our 5ops team, who are building and maintaining all our infrastructure. We’re glad to have Greg Karékinian on board as the latest 5apper, and in his first article he’s going to share a little trick for users of Chef Server and Travis CI. Enjoy!

At 5apps we use Chef to automate our infrastructure, so far in a traditional client/server model. Using Chef Server comes with an extra level of complexity, though: if you’re not careful, your Git repository and the server will get out of sync and you will likely end up scratching your head figuring out what is happening.

Fortunately, there’s a gem for that: knife-inspect, formerly known as health_inspector. I couldn’t live without this Knife plugin and I’m glad to announce that I just took over as the new maintainer (thanks to the original author, Ben Marini!). I actually asked to become the new maintainer after I added support for return codes, which is necessary for using the gem in a continuous integration setting. You will need at least version 0.7.1 (just released yesterday), which fixes a small bug with the return code for data bags.

For continuous integration of our applications we use the Pro service by our friends and office mates at Travis CI. Before this setup, I would run knife-inspect every couple of weeks (when I remembered) and fixed the differences between our Chef repo and Chef server. But as a developer and automation engineer I really like to turn painful manual steps into automated bliss, so I thought about using Travis to run knife-inspect after every push.

While working on this I realized Travis CI gives you secure environment variables so you don’t have to commit a clear-text version of your Chef user’s credentials. Check out Travis CI’s doc for more information. Here’s what the .travis.yml file of our Chef repo looks like (minus irrelevant sections such as notifications):

language: ruby
rvm:
  - 1.9.3
before_script:
  - secret=`openssl rsautl -decrypt -inkey ~/.ssh/id_rsa -in .chef/travis_secret`
  - openssl aes-256-cbc -k "$secret" -in .chef/travis-ci.pem.enc -d -a -out .chef/travis-ci.pem
env:
  global:
    - OPSCODE_USER=travis-ci
script: "bundle exec knife inspect"

And here’s a screenshot of knife-inspect running on Travis CI:

Travis CI knife-inspect

So knife-inspect will now make the build of our Chef repository fail, in case repo and Chef server are out of sync. Here’s an example from our private IRC channel:

20:37 !GitHub gregkare pushed 1 new commit:
  https://github.com/5apps/chef/compare/beefdead...beefdead
20:37 !GitHub [chef] Add some great feature - Greg Karékinian
20:43 !Travis Build status for chef (master:beefdead): Still Failing
  [https://magnum.travis-ci.com/5apps/chef/builds/2055018]
20:46 !GitHub gregkare pushed 1 new commit:
  https://github.com/5apps/chef/compare/beefbeef...deaddead
20:46 !GitHub [chef] Add missing updated preproduction environment - Greg
  Karékinian
20:52 !Travis Build status for chef (master:deaddead): Fixed
  [https://magnum.travis-ci.com/5apps/chef/builds/2055128]

Happy shipping!