Vagrant and Chef-Solo on Windows

Vagrant on Windows

There are a lot of guides out there which explain how to install and configure Vagrant on Linux.  In this guide, we will start with the basics by covering the installation and setup on Windows.  Specifically, the host environment is Windows 7.  When I first tried setting this up on Windows, I followed a few of the popular guides online, but I was not successful.  The so-called “quick-starts” made the process seem like a piece of cake.  As such, you can imagine how I felt when what should have taken me 10 minutes took longer than 3 hours.  For this reason, I will share the tips and tricks which I picked up along the way.  This way, you won’t need to take the scenic route like I did.  We will also cover an example of a specific provisioner, Chef-Solo, and configure a working Apache instance on your Vagrant box.

Installation and Setup

  • Vagrant – Go to https://www.vagrantup.com/downloads.html and download and install the latest version of Vagrant.  That’s the official approach, but for me, I had to downgrade to a previous release. As of the time of this blog, the latest version, 1.9.7, has a known bug on Windows, which causes a process to hang. You can find the details on https://github.com/mitchellh/vagrant/issues/8777. Instead of jumping through unneeded hoops, I solved this problem by downgrading to 1.9.6.  As such, even as new versions are released in the future, if you face similar problems, you may try downgrading to solve them.
    • Boxes are downloaded to %userprofile%/.vagrant.d/boxes by default.  However, these images can accumulate in size, and if you have a separate disk to where you want to download your boxes, you can set a Windows System Environment Variable as such: VAGRANT_HOME=<your custom path>
  • VirtualBox – Go to https://www.virtualbox.org/wiki/Downloads and download and install the latest Windows VirtualBox package. My version is 5.1.24 r117012 (Qt5.6.2), but I have not had to do any downgrade work-around’s with VirtualBox like I did with Vagrant, so your actual experience may vary here.

First Vagrant Box

Once Vagrant and VirtualBox are installed, go to the Command Prompt and run: vagrant init ubuntu/precise64

Notice that you now have a Vagrantfile, which is a configuration file written in Ruby.

Your current directory is your project directory, which is the term for the directory which has your Vagrantfile.

Then run vagrant up

This time around, you will see a lot more output, and should see something like this:

Adding box ‘ubuntu/precise64’ (v20170427.0.0) for provider: virtualbox
Downloading: https://vagrantcloud.com/ubuntu/boxes/precise64/versions/20170427.0.0/providers/virtualbox.box
Progress: 100% (Rate: 454k/s, Estimated time remaining: –:–:–)
Successfully added box ‘ubuntu/precise64’ (v20170427.0.0) for ‘virtualbox’!

Note: If you get a message about the VirtualBox and VM Guest Additions version mismatch, most likely you will not have problems following the rest of the steps in this tutorial, so you can treat this as informational.

Once the box is up, you can vagrant ssh into the box and run your favorite Ubuntu commands!

Provisioner – Chef-Solo

We will now cover how to use a provisioner to install Apache on your Vagrant box, and serve up a custom HTML file.  You do not need to be a Chef expert to follow this example.  You can read up on Chef online to get more details. For this example, remember that Chef uses cookbooks which contain recipes.  Recipes define the configurations which represent the desired states of the resources.

Using a command prompt, go to the directory where your box is running, and execute vagrant destroy, which will destroy your current running instance so that you can configure your Vagrantfile for Chef-Solo.

You can make a backup of your current Vagrantfile, or delete it, because you can always create a new Vagrantfile by running vagrant init.

Now, create a new Vagrantfile with the following code:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
    config.vm.box = "ubuntu/precise64"
    config.vm.network "forwarded_port", guest:80, host:8080
    config.vm.provision "chef_solo" do |chef|
          chef.add_recipe "apache2"
    end
end

This does the following:

  1. Use the Ubuntu 64-bit image
  2. Configure port forwarding; guest is the Vagrant box on which Apache will be running, host is your Windows machine
  3. Set the provisioner as Chef-Solo
  4. Add the apache2 cookbook to the Chef run list

Chef Config

In your current directory, create a cookbooks directory, and a recipes directory under cookbooks.  In the recipes directory, create a file called default.rb.  Add the following code:

execute "apt-get update"
package "apache2"
execute "rm -rf /var/www"
link "/var/www" do
        to "/vagrant"
end
file '/var/www/index-guest.html' do
  content '<html>Welcome to Vagrant! This was file created on your guest. Brought to you by Apache2!</html>'
end

This does the following:

  1. Run an apt-get update which updates the package lists
  2. Install Apache
  3. Remove the /var/www directory, which is the default content directory for Apache
  4. Create a symbolic link from /var/www to /vagrant; /vagrant is the default synced folder from your host (Windows) to your guest (Ubuntu); this will enable you to create files in your project directory (Windows) and serve them from your guest (Ubuntu) Apache instance.
  5. Use the Chef resource file to create a new file on the guest

Create an index-host.html file in your project directory with the following content:

<html>Welcome to Vagrant! This was file was created on your host. Brought to you by Apache2!</html>

At this point, your current directory structure should like this:

<Project Directory>
-cookbooks
  -apache2
    -recipes
      default.rb
index-host.html
Vagrantfile

We are now ready to bring up the box!

Vagrant Up!

From your project directory, run vagrant up.

You will see the usual output as before, but now you will also see:

...
default: Running provisioner: chef_solo...
default: Installing Chef (latest)...
...

This indicates that Chef-Solo is now the provisioner.  At the end of the startup, you can browse to http://localhost:8080/index-host.html.  You will see the HTML page which you created locally.  When you browse to the index-guest.html page, you will see the HTML page which you created with the Chef recipe during the Chef run.  You will see both HTML files in your host project directory and your /vagrant synced folder on your guest.   This is because this directory is a shared space between your host and guest. One strategy to use is creating assets locally, so that these assets will be available on your guest instance at/vagrant.

Summary

We have covered the installation and setup of Vagrant and VirtualBox on Windows.  Along the way, we discussed the Vagrant downgrade work-around as well as setting the VAGRANT_HOME variable to an alternate path.  We then brought up a base Ubuntu box, and SSH’d into the box. Afterward, we created a brand new configuration which declared Chef-Solo as the provisioner for Apache.  We set up our Chef cookbook and recipe to bring up Apache and serve an HTML file from the guest, using port forwarding.  You can move forward and learn about other Chef provisioners like Puppet, and use what you learned here to extend you knowledge.