Skip to content

Instantly share code, notes, and snippets.

@pr3l14t0r
Last active July 19, 2022 10:44
Show Gist options
  • Select an option

  • Save pr3l14t0r/8b350fc7052ccee30a456596fa017c33 to your computer and use it in GitHub Desktop.

Select an option

Save pr3l14t0r/8b350fc7052ccee30a456596fa017c33 to your computer and use it in GitHub Desktop.
This GIST aims to explain how you can leverage the WSL2 from Windows in order to use vagrant+ansible for the provisioning of virtual machines in VirtualBox, installed on the host windows os.

Use vagrant and ansible to provision your VirtualBox-VMs on Windows

This small guide aims to help all fellow windows users out there, who use VirtualBox on the windows-host-os but want to work with vagrant+ansible smoothly. This goal can be achived by leveraging the sharing-functionalities between the WSL2 and the windows host os.

In general, you have to perform the following steps which will be explained in detail down below:

  1. Setup and configure WSL2 on your Windows System
  2. Install a WSL2 distribution (I've used ubuntu)
  3. Install vagrant within the WSL2 distro (see Basics)
  4. Install and configure ansible in the WSL2 distro
  5. Configure networking (see Networking) between WSL2 and Host
  6. Use an ssh key with correct permissions set for ansible (see SSH Keys)

Basics

First of all it is recommended to take a quick look into this guide which explains how WSL2 can be used to run vagrant within the WSL2 distro while actually working with the windows host components. Follow the instructions in order to install Vagrant in your WSL2 distro accordingly.

To access windows resources outside the WSL2 distro, you have to set the following environment variable inside your WSL2 distro:

  • Required: export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1"
    • ensures that vagrant within WSL can access the windows resources, like VirtualBox
  • Required: export PATH="$PATH:/mnt/c/Program Files/Oracle/VirtualBox"
    • adds the location of virtualbox within WSL2 to the path variable
  • Optional: If the base folder is in another location than your home directory, set it accordingly in order to make stuff like vagrant ssh work.
    • export VAGRANT_WSL_WINDOWS_ACCESS_USER_HOME_PATH="/mnt/c/TestDir"

Networking

There is well known issue related to networking when WSL2 is used. The problem is, that the network interface attached to WSL2 cannot see the localhost ip address which prevents vagrant ssh from working. You can either specify the correct addresses etc. manually, or just use the plugin virtualbox_WSL2 thankfully provided by Karandash8.

In your WSL2 distro, run: vagrant plugin install virtualbox_WSL2

This will automatically add the specific port-forwarding configuration to the corresponding VM(s).

Now you have to configure your local firewall accordingly. The ethernet adapter used by WSL2 is set by HyperV from Windows and mostly called something like vEthernet (WSL). To fetch the IP-Address and CIDR-Prefix, run the following powershell command:

Get-NetIPAddress | where {$_.InterfaceAlias -like "*WSL*"} | select InterfaceAlias,IPAddress,PrefixLength

This will output the necessary information that you can use for a firewall rule.

InterfaceAlias  IPAddress                   PrefixLength
--------------  ---------                   ------------
vEthernet (WSL) fe80::2c1f:abd5:d064:253%49           64
vEthernet (WSL) 172.21.240.1                          20

In the example case, the ip range used by the WSL2 ethernet adaptor is 172.21.240.1/20. Use this information to add a firewall-rule.

NOTE: The following example will show you how to create a rule for the Windows-Firewall. If you are using a third-party firewall which does not also process the rules configured for windows-firewall, you have to create the rule manually in your tool! You can use the following settings as a guideline though.

In an administrative powershell session, run:

# Make sure to run the following command as administrator!
New-NetFirewallRule -Name "WSL2LocalHost" -DisplayName "WSL2 to Localhost-VBox Traffic" -Enabled True -Direction Inbound -Profile Any -Action Allow -Protocol TCP -LocalPort "2200-2222" -RemoteAddress "172.21.240.1/20"

The output contains the details of the created rule:

Name                  : WSL2LocalHost
DisplayName           : WSL2 to Localhost-VBox Traffic
Description           :
DisplayGroup          :
Group                 :
Enabled               : True
Profile               : Any
Platform              : {}
Direction             : Inbound
Action                : Allow
EdgeTraversalPolicy   : Block
LooseSourceMapping    : False
LocalOnlyMapping      : False
Owner                 :
PrimaryStatus         : OK
Status                : Die Regel wurde erfolgreich vom Speicher aus analysiert. (65536)
EnforcementStatus     : NotApplicable
PolicyStoreSource     : PersistentStore
PolicyStoreSourceType : Local

If you have the need to add/set/remove ports configured in the rule, use the following command:

# make sure to run as administrator
# This will add the port "1234" to the accepted ports
Get-NetFirewallRule WSL2LocalHost | Set-NetFirewallRule -LocalPort ("2200-2222","1234")

# Verify
Get-NetFirewallRule WSL2LocalHost | Get-NetFirewallPortFilter
Protocol      : TCP
LocalPort     : {2200-2222, 1234}
RemotePort    : Any
IcmpType      : Any
DynamicTarget : Any

Once the rule got applied, (ssh-)traffic from the WSL2 distro will not get blocked any longer.

SSH Keys

The last problem that will occur is related to the SSH key used by vagrant. Vagrant uses a standard insecure_private_key file that ships with community-provided boxes. As this file will be mounted via the /mnt/{DRIVE}/Location/on/Windows paths, the permissions will not get set correctly and can't get changed though chmod. Thus the file will have the unix permissions 777 set and therefore be consided as insecure by ansbile. This will prevent the provisioning accordingly.

To address this issue, you need to have an ssh-keypair located within the native WSL2 distro and use this for the provisioning instead of the insecure_private_key file.

What to do (inside your WSL2 distro):

  1. create a new ssh key

    • ssh-keygen
      • specify the path like: /home/myuser/.ssh/myFile
      • Leave the password blank!
    • Verify that the file and its corresponding .pub file were created: ls -la ~/.ssh
  2. Use the new key in Vagrantfile

# Declare a variable that stores the path to your ssh private key file
SECURE_SSH_PRIVATE_KEY = "~/.ssh/devOps"

# Copy the public key to each VM and add it to known_hosts

Vagrant.configure("2") do |config|
    config.ssh.insert_key = false

    # Insert own ssh key to the machines. 
    # Taken from: https://stackoverflow.com/questions/30075461/how-do-i-add-my-own-public-key-to-vagrant-vm
    vagrant_home_path = ENV["VAGRANT_HOME"] ||= "~/.vagrant.d"
    config.ssh.private_key_path = ["#{vagrant_home_path}/insecure_private_key", "#{SECURE_SSH_PRIVATE_KEY}"]

    config.vm.provision "file", source: "#{SECURE_SSH_PRIVATE_KEY}.pub", destination: "/home/vagrant/.ssh/SecureKey.pub"
    config.vm.provision :shell, privileged: false do |shell_action|
        shell_action.inline = <<-SHELL
            cat /home/vagrant/.ssh/SecureKey.pub >> /home/vagrant/.ssh/authorized_keys
        SHELL
      end

    # < Additional Vagrant stuff >
end

For a working example, take a look into my customized vagrant-file used for a kubernetes cluster deployment (forked from itwonderlab/ansible-vbox-vagrant-kubernetes. You have to uncomment the respective lines that will inject a secure ssh key into the VMs.

With all of those prerequisites met, you are finally able to run vagrant+ansible from within your WSL2 distro while working with your windows host as operating system. :)

I suggest using VisualStudio code connected to your WSL2 distro. This enables you to easily edit your files mounted into WSL an execute the allmighty vagrant up command directly. :)

@ArgonQQ
Copy link

ArgonQQ commented Aug 23, 2021

👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment