Speedup Test Kitchen Vagrant Infrastructure Code Testing

Test Kitchen together with Vagrant is a wonderful way to test out your infrastructure deployment and orchestration code. It makes test-driven development especially easy by allowing you to test locally using virtual machines. However, those of you who do a lot of testing with Test Kitchen and Vagrant would know that waiting for tests to complete can be painfully long. This is especially true when with every test run the same packages have to be downloaded over and over again. Or when Vagrant decides to update the Virtual Box Guest Addition plugin every time you run your test suites.

Christine Draper has an excellent post which allows one to remove much of the waiting and make test runs instant. These basically involve installing two Vagrant plugins vagrant-cachier and vagrant-omnibus and disabling automatic Virtual Box Guest Addition plugin updates.

I would not detail why and how here, as details are already present in Christine’s post which I have referenced. I would rather provide you with a Vagrantfile template that can be used with Test Kitchen so that we can make it use the two plugins and disable Virtual Box Guest Addition plugin updates.

Below is the content which you will need to write to a file named Vagrantfile.erb

Vagrant.configure("2") do |c|
  c.vm.box = "<%= config[:box] %>"
  c.vm.box_url = "<%= config[:box_url] %>"

  if Vagrant.has_plugin?("vagrant-cachier")
    c.cache.auto_detect = true
    c.cache.scope = :box

  if Vagrant.has_plugin?("vagrant-omnibus")
    c.omnibus.cache_packages = true
    c.omnibus.chef_version = "11.16.4"

  c.vbguest.auto_update = false

<% if config[:vm_hostname] %>
  c.vm.hostname = "<%= config[:vm_hostname] %>"
<% end %>
<% if config[:guest] %>
  c.vm.guest = <%= config[:guest] %>
<% end %>
<% if config[:username] %>
  c.ssh.username = "<%= config[:username] %>"
<% end %>
<% if config[:ssh_key] %>
  c.ssh.private_key_path = "<%= config[:ssh_key] %>"
<% end %>

<% Array(config[:network]).each do |opts| %>
  c.vm.network(:<%= opts[0] %>, <%= opts[1..-1].join(", ") %>)
<% end %>

  c.vm.synced_folder ".", "/vagrant", disabled: true
<% config[:synced_folders].each do |source, destination, options| %>
  c.vm.synced_folder "<%= source %>", "<%= destination %>", <%= options %>
<% end %>

  c.vm.provider :<%= config[:provider] %> do |p|
<% config[:customize].each do |key, value| %>
  <% case config[:provider]
     when "virtualbox" %>
    p.customize ["modifyvm", :id, "--<%= key %>", "<%= value %>"]
  <% when "rackspace", "softlayer" %>
    p.<%= key %> = "<%= value%>"
  <% when /^vmware_/ %>
    <% if key == :memory %>
      <% unless config[:customize].include?(:memsize) %>
    p.vmx["memsize"] = "<%= value %>"
      <% end %>
    <% else %>
    p.vmx["<%= key %>"] = "<%= value %>"
    <% end %>
  <% end %>
<% end %>


The file Vagrantfile.erb can be in the same directory as the .kitchen.yml file and can be referenced in .kitchen.yml in the “platforms” section as follows:

  - name: centos-6.4
      vagrantfile_erb: Vagrantfile.erb

That’s about it. Next time you test your infrastructure code, don’t forget to use the Vagrantfile.erb template. You will be pleased to see how quickly the tests finish.

Ovais is a storage architect with keen focus on reliability, efficiency and performance of OLTP databases, more specifically MySQL. He currently works at Uber on ensuring storage reliability and scalability. Previously, he helped different web properties scale their MySQL infrastructure. He also worked at Percona as a Senior MySQL consultant and at a few other startups in various capacities.