Back to blog home

Tips for Vagrant and Chef

For those of you cooking up a storm with Vagrant and Chef, these tips might help when creating your VMs (Virtual Machines). These are things that we've discovered and found useful while working on projects at Inviqa. If we thought they were useful, we thought you might too!

Keep your base boxes up to date

If you're working on a long-lived project using Vagrant boxes, chances are you set up your base box, spent some time getting it configured how you liked, then forgot about it. If part of your provisioning process is to bring packages up to date, then the longer your project runs, chances are the longer this step takes, due to getting more updates. If you rarely rebuild your box you probably won't notice this, but if you regularly 'destroy' and 'up your box, this can be reduced by updating your base box to include these updates. New developers to your project will also thank you for not spending hours watching updates scroll past, or maybe they won't - if they were hoping for an extra coffee break ;)

To take this even further, you could use VeeWee to build a custom box with all the packages pre-installed, further shortening the provisioning step.

Vagrantfile - Not just static configuration!

One realisation we came to on a couple of projects independently, and have since discussed and refined, is the the Vagrantfile is executed rather than just read. This happens early in the start up process, so it's a quick way to check that resources are available rather than waiting for half an hour while your VM builds and provisions, only to find that you forgot to place your custom widget config in your dooberry directory and, apart from the tweets you read in the lull, you've just lost the last half an hour. do |config|
  if ENV['UNIQUE_KEY'].nil? then
    puts "The UNIQUE_KEY environment variable must be set to a unique
value within the project, i.e. your username"
  nfs_status = (ENV['WINDOWS']) ? false : true
  #Share the code from host
  config.vm.share_folder "Sites", "/mnt/Sites", "#{ENV['HOME']}/Sites", :nfs => nfs_status
  #Put some cached files on the host to save downloading on rebuild
  config.vm.share_folder "chef-cache",
  config.vm.share_folder "chef-file-store",
  #Common config shared between multiple VMs
  def shared_chef_config(chef)
    chef.chef_server_url = ""
    chef.validation_key_path = "~/Sites/inviqa/tools/chef/.chef/inviqa.pem"
    chef.validation_client_name = "inviqa"
    # Set the environment for the chef server
    chef.environment = "development"
    # Put the client.rb in /etc/chef so chef-client can be run w/o specifying
    chef.provisioning_path = "/etc/chef"
    # logging
    # chef.log_level = :debug
  def set_node_name(chef, node_name)
    chef.node_name = "#{ENV['CLIENT_KEY_NAME']}-#{node_name}"
  #Web VM
  config.vm.define :web do |web_config| :hostonly, ""
    web_config.vm.provision :chef_client do |chef|
      shared_chef_config chef
      set_node_name(chef, "web")
  config.vm.define :api do |api_config| :hostonly, ""
    api_config.vm.provision :chef_client do |chef|
      shared_chef_config chef
      set_node_name(chef, "api")

Knife_EC2 - Not the sharpest tool in the box

I've been doing some work with chef and EC2 and have found a few idiosyncrasies that can make it challenging to use. It works really well for what it does, firing up EC2 instances and bootstrapping chef onto them. Where I ran into problems was trying to script EC2 instances to start using knife ec2 server create. I'd gotten fed up of typing a command line as long as my arm and, as is sensible, put the defaults into my knife.rb config file. Once I was happy with how it was working, I sprinkled a few of these commands judiciously through a script and ran it. These calls to knife were config driven, so they had the full command line with different options to start different AMIs, different AMIs in different regions along with various other things.

To my surprise, all these options were blissfully ignored in favour of my config file.

This behaviour was so unexpected that it took me a little while to spot it. I was busily debugging my script thinking I'd made a typo somewhere, or was loading the wrong config. Hopefully, forewarned will be forearmed and you won't fall into this trap, unlike the many others who have previously when I raised it on the chef mailing list.

If you want to keep an eye on it, there is a bug raised against it on the Chef bug tracker. Time permitting, I hope to brush up on my Ruby skills and pitch in to help on this, rather than just moaning about what is otherwise a great knife plugin, but I'm happy for someone else to get there first.

Does your source control match your deployed recipes?

When working with chef, you quickly find out the pitfalls of having changes made through the opscode GUI and changes being pushed to your organisation via knife. With good discipline you can push all changes from files via knife and commit the changes back to source control. However, we all know other developers who are not as rigorous as us. If you don't this may be you, dear reader, and it's time to mend your ways.

Whether you're a lone developer trying to implement good practices, or working on a larger project where you're trying to enforce encourage them, health_inspector is a useful tool to do this.

It allows a quick comparison between your local repository and your chef server to check that your files are in sync. It's a relatively young project, so may be a little rough round the edges, but the developer is active and responded quickly when I identified a few bugs, fixing them quickly and providing a new release.

When discussing this with a colleague, he mentioned a useful knife plugin for bringing out of sync chef repos back into sync, knife-align. The guys behind that have also developed knife-consistency which looks to do a similar job to health_inspector in a knife plugin. I've not had a chance to look at it either of these yet, but being aware of all the tools at hand puts you in a better position to solve the problem, should it arise.

Over to you!

Are you doing something interesting with Vagrant and/or Chef? While we've been using these tools for a while now, we're still refining our approach and sharing our findings between projects. By sharing them with you, hopefully you'll figure out new things to do and share them with us. If you've got any interesting techniques or improvements on those listed above, please comment as we're always looking for new and interesting uses for technology.

If this sounds like the sort of thing you're interested in doing, Inviqa are hiring across the UK, so drop us a line at [email protected] and come and contribute.