Over the last year I’ve discovered and fell in love with the Vagrant project. Vagrant is a wonderful tool for getting started with cloud-based automation and devops. One of the problems it aims to solve is the idea that code “works on my machine“. While vagrant does indeed offer Windows as a first-class supported citizen, there’s still surprisingly little support around tooling or examples of how this can be achieved with an ASP.Net application. I see this toolset being very critical in the future of software development and cloud computing. So with that said, and myself being primarily a .Net developer, I wanted to start doing my part to help make ASP.Net and Windows Server based development with these tools much easier.

Today, I’ll walk you through a few easy steps to get started with a Windows VM on Vagrant, and do some basic provisioning. These steps can be followed both on OSX and on Windows, with some slight variation in installing the tools.

A Quick Introduction

Vagrant is a tool used to support one of the core tactics of the devops movement, and that’s to get your infrastructure (that is, the servers that your application is running on) into source code. If your infrastructure could be built from source code and tools, it can then be checked into source control. Because it’s in source control, each developer is now also capable of running the exact same VM as you and more closely replicating the production environment. One important step towards obliterating the “works on my machine” excuse and streamlining your build process.

Each Vagrant working copy has a backing baseline “box” that is a pre-built virtual machine for a specific provider, such as Virtualbox, VMWare, or even a cloud provider such as EC2 / Azure / Openstack. Once the baseline box has been downloaded and working copy box has launched, you define provisioning steps to tell vagrant how to install the source code onto your new VM. Provisioning tools such as Puppet and Chef are great for this, (and vagrant has full support for them) because the same provisioning manifests can also be used for provisioning your development, QA, staging, and production servers.

Installing the Tools

Vagrant is a command line tool, so everything you’re doing here is going to be command line based. Given that, I would highly recommend using a good command line shell such as Cmder for Windows or Fish for OSX. For package installers, I would recommend Chocolatey for Windows and Homebrew (and Cask) for OSX

The two tools we we need to install are Vagrant and Virtualbox.

OSX (assumes Homebrew and Cask are installed)

brew install vagrant

brew cask install virtualbox

Windows (Assumes Chocolatey is installed)

cinst vagrant

cinst virtualbox

Initializing your Box

For this example, we’ll take an existing Windows Vagrant box and initialize it. This box is Windows Server 2012R2 based and is running a trial edition of Windows. It is built and hosted by me. It’ll likely take a few hours to download because of this, (my hosting isn’t the fastest, but it’s very cheap) but you can re-host the same box on your own servers for faster downloading for other developers if needed. You can check out this and other Windows-based boxes that I maintain on my Vagrant Cloud site.

We’ll start with an empty working directory. This command should always be run at the root of the project that will be running your application (usually your git/svn working copy root)

vagrant init kensykora/windows_2012_standard

This creates a boilerplate Vagrantfile (which is just a ruby script) in the current directory. This is a file you will want to commit to version control. If you open up this file, you’ll notice a lot of commented out documentation for getting started in configuring your Vagrant environment. I would recommend that at some point you begin to explore these options, or view the full documentation at docs.vagrantup.com.

Now we need to download and “up” the box (meaning bring it online).

vagrant up

This will begin downloading the box, and once finished, the box will be brought online. You’ll also notice a new folder has been created called .vagrant which houses the storage for this new VM.

Additionally, Vagrant also stores a clean copy of the box in a local spot in your home directory so that if you in the future, try to initialize another box with the same base box, you won’t have to download it again. Because this box is also associated with Vagrant Cloud, Vagrant will check for updates and offer for you to update the base box. This particular box I am planning to maintain and provide updates to on a quarterly basis or more.

You can control Vagrant’s default behavior through environment variables. For example, you can change the location where base boxes such as this one are stored with VAGRANT_HOME=d:\.vagrant and the default Vagrant provider with VAGRANT_DEFAULT_PROVIDER=vmware_desktop .

Connecting to the Box

You’ll notice that once the box is powered up, you don’t see any Window into the box as you would normally with Virtualbox. This is by design, (When you launch a cloud instance via the command line, you don’t see it’s screen either) but can be changed in the Vagrantfile. We can, however, remote into the box via RDP.

vagrant rdp

username: vagrant

password: vagrant

This is the standard vagrant username and password for all vagrant boxes. This is intentionally insecure, as all base vagrant boxes are only intended for development purposes. You should never attempt to migrate these to any other environment that is publicly accessible.

Note: As of Vagrant 1.6.3 there is a known issue causing `vagrant rdp` calls to fail on Windows hosts. This is not an issue in OSX and is fixed for a future 1.6.4 release: mitchellh/vagrant#3973 – As a workaround, you can manually open your RDP client and connect to 127.0.0.1:2200, or whatever port is displayed on the output of “default: 3389 => 2200 (adapter 1)” output of the `vagrant up` command from earlier.

Provisioning the Box

A baseline box isn’t much good on its own — What we will ultimately want to do is configure it to run our application from our source code. Let’s start by creating a basic HTML page to host on IIS and get it running.

index.html

<html> <body> <p>Hello World!</p> </body> </html>

Put this file in the root of your directory. Now, let’s write a powershell script to install IIS and configure the default site.

Configure.ps1

$windowsFeatures = @( 'Web-Server', 'Web-WebServer', 'Web-Mgmt-Console', 'Web-Mgmt-Tools' ); Install-WindowsFeature -Name $windowsFeatures #Workaround for IIS Permissions Issues New-SmbShare -Name vagrant -Path C:\vagrant -FullAccess @("IIS_IUSRS","IUSR", "Administrators") Remove-Website 'Default Web Site' New-Website -Name MyWebsite -Port 80 -HostHeader * -PhysicalPath \\localhost\vagrant

And finally, update the Vagrantfile to setup script provisioning and port forwarding for IIS.

Vagrantfile

# -*- mode: ruby -*- # vi: set ft=ruby : # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "kensykora/windows_2012_r2_standard" config.vm.network "forwarded_port", guest: 80, host: 8080 config.vm.provision "shell", path: "Configure.ps1" end

You may want to simply replace your Vagrantfile with the above contents, but if you wish to simply modify the one that’s there, just add the two lines config.vm.network and config.vm.provision directly underneath the already existing config.vm.box . SublimeText with the sublime-vagrant module works great for being a Vagrantfile editor.

Once you’ve made these changes, let’s force the box to re-provision (it will think it has already provisioned since your original vagrant up) .

vagrant provision

Now, test it out by opening your browser on your host (not the VM) to http://localhost:8080 – You should now have a working application VM running your website! Feel free to make changes to the index.html page and watch them update on your VM! This shows that you are able to use the VM without any need for RDP or having it visible on your desktop.

Full Source Example: https://gist.github.com/kensykora/889452478e622078910c

What’s Next?

Now that we’ve successfully launched our Vagrantbox, we can remote in and use it as a sandbox to do our development, test software applications, evaluate third-party software, and pretty much anything you’d want to do with a VM — all from the command line and all without having to build the VMs ourselves. Of course, we can if we want to, and in future posts I’ll cover this topic as well as provisioning them with CM tools like Puppet, and using your infrastructure code to deploy to dev and prod servers. Feel free to try out the same steps above with my other boxes listed at Vagrant Cloud, or any other boxes listed there.