Quick links Vagrant resources | Virtual workstations | Vagrant boxes | Packer templates
This repository contains Windows-based virtual workstations for .NET, SQL and infrastructure development using Vagrant with Hyper-V and VirtualBox.
Contents Overview | Getting started | Usage | Contributing | Resources
This repository contains Windows-based virtual workstations for the following scenarios:
- .NET development with Visual Studio 2017, 2015 and 2010.
- SQL development with SQL Server Management Studio 17 and SQL Server 2014.
- Infrastructure development with Vagrant using Docker, VirtualBox and AWS.
All of them support an easy, source-controlled way of installing and configuring the most common development tools for the related stacks, and the management of the source code of your projects, based on Vagrant with Hyper-V / VirtualBox and Chef:
- Installing core features, packages and managing OS settings.
- Using different versions of Visual Studio and SQL Server.
- Managing Vagrant plugins and downloading boxes.
- Pulling Docker images.
- Configuring AWS profiles.
- Working with Git and SVN repositories.
- Managing NuGet sources.
This way you can easily create the same workstations anytime, anywhere, and instead of writing extensive documentation, you can simply share the ready to use environments with your teammates and contributors. Of course, you can extend the above options freely with any of your own configuration and provisioning steps.
In this section Installing the tools | Creating your first workstation
Note This section assumes you are familiar with the basics of Vagrant. If that's not the case, it's recommended that you take a quick look at its getting started guide.
Note The workstations have been tested on Windows hosts only, but they are supposed to run on any other platform as well, given that the actual virtualization provider (e.g. VirtualBox) supports it. Let me know if you encounter any issues and I'm glad to help.
In this section Using Hyper-V | Using VirtualBox
Follow the steps below to install the required tools:
- Install Vagrant.
- Install the Chef Development Kit.
- Install the following plugins:
- Install the tools for the virtualization provider you want to use.
Note Other virtualization providers that you might use will not work when Hyper-V is enabled. See Hanselman's post for switching between them easily.
- Enable Hyper-V. You will need Windows 10 or Windows Server 2016 version 1607 or later on the host.
- Optionally, if you plan to use Hyper-V by default, add the environment variable
VAGRANT_DEFAULT_PROVIDER
with the value ofhyperv
to prevent specifying it every time a machine is booted. - Optionally, add the environment variable
VAGRANT_LINKED_CLONE
to save some disk space using differencing disks. - Optionally, add the environment variables
VAGRANT_SMB_USERNAME
andVAGRANT_SMB_PASSWORD
with your credentials on the host to prevent Vagrant from asking it every time a machine is booted.
- Optionally, if you plan to use Hyper-V by default, add the environment variable
- Create a virtual switch to be used with Vagrant with access to the external network.
- Optionally, add the environment variable
VAGRANT_NETWORK_BRIDGE
with the value of the name of the virtual switch you've created to prevent Vagrant from asking for it every time a machine is created.
- Optionally, add the environment variable
- Install VirtualBox. It is recommended to have VirtualBox version 5.1.22 or later on the host.
- Optionally, if you plan to use VirtualBox by default, add the environment variable
VAGRANT_DEFAULT_PROVIDER
with the value ofvirtualbox
to prevent specifying it every time a machine is booted. - Optionally, add the environment variable
VAGRANT_LINKED_CLONE
to save some disk space using linked clones.
- Optionally, if you plan to use VirtualBox by default, add the environment variable
Note Booting a workstation for the first time can take a significant amount of time. If you have a slow connection, downloading the Vagrant boxes - usually several GBs for Windows guests - might require some patience and retries. Creating another machine from the same box later though will reuse the already downloaded one of course.
Note Configuring the core OS after Sysprep (to support actually unique virtual machines) and provisioning the workstations (e.g. installing the custom tools not included in the Packer templates) by default happens during the initial boot as well. However, starting the machines again later will not need these steps, so the process will be significantly faster.
Note The example in this section creates a workstation with a sample configuration by default, focusing on demonstrating the management of machines in general. You will see the details of how to customize it according to your preferences later.
You are now ready to create your workstations with Vagrant.
Clone this repository and navigate to the root directory of the clone using your shell. Then, enter the directory of your personal environment to list the available machines:
clone$ cd src/people/me
clone/src/people/me$ vagrant status
The output will be something similar to this:
work not_created (hyperv)
playground not_created (hyperv)
private not_created (hyperv)
The list shows the three default workstations, work
intended to support the projects you work on, playground
for generic experiments, and private
for anything else, like communication or generic office work. None of these exsit yet, so for example, to create the playground
one, simply invoke vagrant up
:
clone/src/people/me$ vagrant up playground
Now, it's time to be patient. The box - in this case, by default with Visual Studio 2017 Community including Windows Server 2016 Standard - will be downloaded and the machine will be provisioned before the first use to include all the components this repository supports. If this is not the configuration that you want, you can terminate the process anytime.
Once the machine is ready, you can connect to it with RDP or open a remote PowerShell shell using the default credentials, vagrant
for both the user name and password:
clone/src/people/me$ vagrant rdp playground
clone/src/people/me$ vagrant powershell playground
Later, you can check the status of your machines by typing vagrant status
again in the same directory or vagrant global-status
anywhere to list all the machines on your host.
clone/src/people/me$ vagrant status
work not_created (hyperv)
playground running (hyperv)
private not_created (hyperv)
$ vagrant global-status
id playground hyperv running clone/src/people/me
When you've finished with your work, you can shut down the machine with vagrant halt
. This will persist the machine's state, so next time when you invoke vagrant up
, it will boot much more faster than for the first time, and your files and settings will be preserved.
clone/src/people/me$ vagrant halt playground
If you no longer need a machine, you can destroy it. As expected, this will wipe it completely from your system (on the next vagrant up
, it will be provisioned again from scratch):
clone/src/people/me$ vagrant destroy playground
The box will remain on your system after destroying the machine as vagrant box list
reports it, as other machines might still use it. You can use vagrant box remove
to clean it up if you no longer need it.
In this section Basics | Components | Stacks | Projects | People
Note At this point you might want to fork this repository and create your own branch to save your changes and to compare your workstations easily with others.
Take a moment to realize that this might have been the last time you installed something for your workstations manually.
In this section Configuration | Provisioning
This repository uses custom Vagrant extensions to enable creating and reusing dynamic configurations based on YAML and ERB for the most common machine parameters and provisioning options.
For example, you can define some reasonable defaults to be applied to every configuration:
# src/components/core/vagrant.yml
core:
provider:
memory: 4096
cpus: 2
This means that by default the machines will allocate 4 GB RAM and 2 virtual CPUs.
Also, you can define how components, like the core OS is being provisioned:
# src/components/os/vagrant.yml
core:
chef:
cookbooks:
- gusztavvargadr_workstations_os
json:
gusztavvargadr_workstations_os:
requirements:
locales:
system: en-US
ui: en-US
user: en-US
datetime:
timezone: UTC
This shows that the custom OS cookbook will be used for provisioning, and the specified values, in this case, en-US
for all the locales and UTC
for the timezone will be set. The cookbooks provide complete samples for the scenarios they support so you can define only the options you need.
YAML files are processed as ERB-templates first, so for example you can dynamically set the host's timezone for the guest:
timezone: <%= `tzutil /g`.strip %>
This approach can be also used to e.g. pass secrets or other sensitive information to the guests without hard-coding them, retrieving the values for example from host environment variables dynamically.
You can also define further parameters for Vagrant, in this case, a base box specifying the Visual Studio version being used:
# src/components/vs/vagrant.yml
core:
includes:
- components/core/core
17c:
includes:
- components/vs/core
box: w16s-vs17c
In this case the configuration named components/vs/17c
will use the Visual Studio 2017 Community box including Windows Server 2016 Standard. This options is very useful for tools which take significant time to install, so instead of applying them on the first boot, they can be already included in the Vagrant boxes.
You can also see how the existing configuration is being reused. components/vs/17c
includes components/vs/core
, which in turn includes the above components/core/core
(specifying the memory and the CPU settings). As the list notation suggests, you can include any number or other configurations. If you specify a single value (like the box
) defined earlier, it will be overridden. Collections (for example, the list of cookbooks
) will be merged, the new values being added after the existing ones.
Components like to appear in groups to form stacks, like using a dedicated .NET version and the related hosting options for local development. For example, for .NET Core you can define to use Docker with the usual images:
# src/stacks/dotnetcore/vagrant.yml
core:
includes:
- stacks/dotnet/core
- stacks/infrastructure/dockere
chef:
json:
gusztavvargadr_workstations_dockere:
profiles:
images:
microsoft/dotnet:sdk-nanoserver:
library:
includes:
- stacks/dotnetcore/core
- stacks/dotnet/library
web:
includes:
- stacks/dotnetcore/core
- stacks/dotnet/web
chef:
json:
gusztavvargadr_workstations_dockere:
profiles:
images:
microsoft/aspnetcore-build:nanoserver:
The referenced generic .NET configuration specifies the default Visual Studio version which you've seen before and includes NuGet as well:
# src/stacks/dotnet/vagrant.yml
core:
includes:
- components/vs/v17c
- components/nuget/core
- stacks/infrastructure/core
library:
includes:
- stacks/dotnet/core
web:
includes:
- stacks/dotnet/core
Stacks aren't of course l'art pour l'art, but to be used in projects. For example, to define the core repositories of the one and only IdentityServer, you can use the following configuration:
# src/projects/identityserver/vagrant.yml
core:
includes:
- components/git/core
chef:
json:
gusztavvargadr_workstations_git:
profiles:
workspaces:
identityserver:
address: https://github.com/identityserver
directory: /Users/vagrant/Repos/identityserver
v4:
includes:
- projects/identityserver/core
- stacks/dotnetcore/library
- stacks/dotnetcore/web
chef:
json:
gusztavvargadr_workstations_git:
profiles:
workspaces:
identityserver:
repositories:
IdentityServer4:
directory: v4/core
IdentityServer4.AccessTokenValidation:
directory: v4/accesstokenvalidation
IdentityServer4.Samples:
directory: v4/samples
This configuration, being referenced in your workstation will check out the mentioned repositories using Git, and install the tools and pull the images as you've seen above.
Finally, you can define your workstation to include projects like this:
# src/people/me/vagrant.yml
work:
includes:
- components/os/w16s
- projects/identityserver/v4
default: true
And have your Vagrantfile
reference the YAML configuration:
# src/people/me/Vagrantfile
directory = File.dirname(__FILE__)
require "#{directory}/../../Vagrantfile.core"
Vagrant.configure('2') do |config|
gusztavvargadr_workstations_vm config, directory, 'work'
end
This is a quick introduction of what happens behind the scenes when you invoke vagrant up
.
Even if being run in a VM with Hyper-V or VirtualBox, Windows still loves to be restarted, and this is especially the case during provisioning, when e.g. Windows Features or specific tools get installed. To support those scenarios when provisioning would require the use of another component which just got installed, but it requires a restart, all the custom cookbooks support being executed in different stages, and the custom Vagrant extension will restart the machine between them.
In the requirements
stage core settings like Windows Features and environment variables get installed and configured.
After those have been set up correctly, the tools
stage is used to install e.g. Chocolatey packages or applications with native installers.
Finally, in the profiles
stage all the tools can now be used properly, for example, to clone Git repositories or manage NuGet sources.
In this section Core | OS | Visual Studio | SQL Server | Vagrant | Docker | AWS | Git | SVN | NuGet
See below the list of components with their features supported out of the box.
- Sets environment variables
- Enables Windows Features
- Installs Chocolatey packages
- Installs native packages
- Copies files to the host
- Selects a box with the core OS preinstalled
- w10e - Windows 10 Enterprise
- w16s - Windows Server 2016 Standard
- Configures locales
- Configures timezone
- Selects a box with Visual Studio preinstalled
- v10p - Visual Studio 2010 Professional
- v15c - Visual Studio 2015 Community
- v15p - Visual Studio 2015 Professional
- v17c - Visual Studio 2017 Community
- v17p - Visual Studio 2017 Professional
- Selects a box with SQL Server preinstalled
- v14d - SQL Server 2014 Developer
- Installs Vagrant
- Installs plugins
- Adds boxes
- Installs Docker Community Edition (Edge) (requires Hyper-V host and Windows Server 2016 guest)
- Pulls Docker images
- Installs Docker Enterprise Edition (requires Windows Server 2016 guest)
- Pulls Docker images
- Installs the AWS command-line tools
- Configures AWS profiles
- Installs Git
- Clones public or private repositories
- Installs SVN
- Checks out public or private repositories
- Installs NuGet
- Adds sources
In this section .NET | SQL | Infrastructure
See below the list of stacks with their components configured out of the box.
- Defines the base box for Visual Studio
- Configures tools and settings for .NET class libraries
- Configures tools and settings for .NET web applications
- Configures tools and settings for .NET Core class libraries including Docker
- Configures tools and settings for .NET Core web applications including Docker
- Configures tools and settings for .NET Framework class libraries
- Configures tools and settings for .NET Framework web applications
- Defines the base box for SQL Server versions
- Installs SQL Server Management Studio 17
- Installs Vagrant with Chef, Packer and the related Vagrant plugins
- Installs either:
- Docker Community Edition
- Docker Enterprise Edition
- VirtualBox
- AWS command-line tools
Below is a list of a few sample projects to demonstrate the grouping of source code with the required development and deployment tools:
Using Git:
- GitHub
projects/github/git
- ASP.NET Core Logging
projects/aspnet/logging
- IdentityServer
projects/identityserver/v3
projects/identityserver/v4
Using SVN:
- Apache
projects/apache/log4net
Your actual workstations reference the above components, stacks and projects and now can ask Vagrant to create them.
clone$ cd src/people/me
clone/src/people/me$ vagrant up (work|playground|private)
The current samples contain only a single personal configuration, but this approach can be used to define baseline configurations for teams or organizations. Simple create a new folder within src/people
for your entities, and include the projects and stacks you require as you've seen above. Then include the team or organizaton in your personal one according to your current membership or projects you want to work with.
Any feedback, issues or pull requests are welcome and greatly appreciated. Chek out the milestones for the list of planned releases.
This repository could not exist without the following great tools: