I have recently started using Vagrant with VirtualBox to isolate development environments for several projects on my Ubuntu. In this way I can create a clean development environment with preinstalled softwares easily.

In this tutorial I will create a new Windows 10 box with Visual Studio 2015. I would like to document the main steps of creating the template virtual machine without going into details about configuration possibilities of the components I use.

The main components

  • Vagrant: This is used for managing template virtual machines (boxes) and create, manage and destroy virtual machine instances from these boxes easily.
  • VirtualBox: The desktop virtualization product I use with Vagrant, but you can use Vagrant with other VMs as well (e.g VMWare, Hyper-V).
  • Packer: It is used to create template boxes for Vagrant. It installs and preconfigures virtual machines with several OSs. It supports other virtualization infrastructures too.
  • Packer Windows templates: Packer configuration files and scripts for creating Windows boxes.

Steps

Creating Windows 10 base box

  1. Download and intall Vagrant then install winrm-fs plugin, this will be required for running provision script on Windows 10 guest:

    vagrant plugin install winrm-fs
    
  2. Install VirtualBox.

  3. Download Packer from http://www.packer.io/downloads.html and extract e.g. into ~/packer directory.

  4. Download packer templates from https://github.com/joefitzgerald:

    git clone https://github.com/joefitzgerald/packer-windows.git
    
  5. Download Windows iso and place in packer-windows/iso folder. I downloaded en_windows_10_multiple_editions_x64_dvd_6846432.iso from my MSDN account.

  6. By default the Windows 10 template will create C: drive with size 60GB, I changed it in windows_10.json under virtualbox-iso builder. You can make another configuration changes here, like memory amount or CPU count:

    "type": "virtualbox-iso",
    ...
    "disk_size": 184320,
    
  7. Open packer-windows/answer_files/10/Autounattend.xml and find <ProductKey> element and enter valid product key under <Key> element:

    <ProductKey>
        <Key>XXXXX-XXXXX-XXXXX-XXXXX-XXXXX</Key>
        <WillShowUI>Never</WillShowUI>
    </ProductKey>
    
  8. Generate SHA1 hash for the ISO

    sha1sum en_windows_10_multiple_editions_x64_dvd_6846432.iso
    
  9. Execute packer in the packer-windows directory by providing iso name and generated hash. The -only=virtualbox-iso tells that only VirtualBox target will be created:

    ~/packer/packer build -var iso_url=./iso/en_windows_10_multiple_editions_x64_dvd_6846432.iso -var iso_checksum=60cce9e9c6557335b4f7b18d02cfe2b438a8b3e2 -only=virtualbox-iso windows_10.json
    
  10. This will create and preconfigure the reusable VirtualBox compatible Vagrant box with name windows_10_virtualbox.box (install windows updates, virtualbox guest additions, vagrant provision tools, etc).

  11. Import the box into vagrant with name windows10:

    vagrant box add windows10 ./windows_10_virtualbox.box
    

After this step vagrant instances can be created using the bare Windows 10 box.

Install Visual Studio 2015 and configure provision script

Now, I would like to install Visual Studio, so I create a vagrant instance using windows10 box, install Visual Studio and then export the box.

  1. Create a new VM:

    mkdir windows10_vs2015
    cd windows10_vs2015
    vagrant init windows10
    
  2. Enable gui in the created Vagrantfile by uncommenting the following lines:

    config.vm.provider "virtualbox" do |vb|
        vb.gui = true
    end
    
  3. Turn on the VM:

    vagrant up
    
  4. Install Visual Studio 2015 and do any necessary modifications of the VM.

  5. I usually create provision script which installs Chocolatey and other softwares using it. The provision script will be executed when vagrant up is called at the first time on the exported box. Create windows10_vs2015/provision/provision.ps1 script:

    iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
    chocolatey feature enable -n allowGlobalConfirmation
    choco install totalcommander
    choco install resharper
    choco install gitextensions
    choco install notepadplusplus
    choco install GoogleChrome
    choco install kdiff3
    choco install yed
    choco install atom
    choco install webstorm
    choco install haroopad
    choco install libreoffice
    choco install foxitreader
    choco install consolez
    
  6. Create new windows10_vs2015/Vagrantfile.pkg file, this will be packaged into the box containing base configurations for the box (the local Vagrantfile in the actual instance’s folder inherits this):

    Vagrant.configure("2") do |config|
        config.vm.communicator = "winrm"
    
    
        config.winrm.username = "vagrant"
        config.winrm.password = "vagrant"
    
    
        config.vm.guest = :windows
        config.windows.halt_timeout = 15
    
    
        config.vm.network :forwarded_port, guest: 3389, host: 3389, id: "rdp", auto_correct: true
        config.vm.network :forwarded_port, guest: 22, host: 2222, id: "ssh", auto_correct: true
    
    
        config.vm.provider :virtualbox do |v, override|
            v.gui = true
            v.customize ["modifyvm", :id, "--memory", 2048]
            v.customize ["modifyvm", :id, "--cpus", 2]
            v.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ]
        end
    
    
        config.vm.provision "shell" do |s|
          p = File.expand_path("../", __FILE__)
          s.path = p + "/provision/provision.ps1"
        end
    end
    
  7. Now export the modified virtual machine:

    vagrant package --output windows10_vs2015.box --vagrantfile ./Vagrantfile.pkg --include ./provision/*
    
  8. After executing the command, windows10_vs2015.box will be created in the current current directory.

  9. Import the created box into vagrant using the following command:

    vagrant box add --name windows10_vs2015 windows10_vs2015.box
    

Testing the box

  1. Create a new VM and up the box:

    mkdir windows10_vs2015_test
    cd windows10_vs2015_test
    vagrant init windows10_vs2015
    vagrant up
    

After executing the command you will have a Windows 10 box with Visual Studio 2015 and preinstalled softwares you configured in provision script.