WSL2,Vagrant,VirtualBoxを使ってAnsibleのテスト環境を構築する方法

今回は下記の環境下でAnsbileのテスト環境を構築する方法を紹介する。

ネットの記事では簡単に実装しているものが多いが、今回はハマりにハマったので備忘録としてまとめておく。

Environment

  • Host: Microsoft Windows [Version 10.0.19043.2251]
  • Ubuntu-18.04 (WSL2)
  • Vagrant 2.2.6 (WSL2上にinstall)
  • VirtualBox 6.1.36 r152435 (Qt5.6.2) (WIndowsのHost側にinstall)

今回の要件は、WSL2上のAnsibleからHost側のVirtualBoxにSSHでアクセスできるようにしたい。

特に重要なのは、VirtualBoxのバージョンを6.1.14以上に設定すること。このバージョン以上でないとWSLと VirtualBoxを共存させることができない。なお、筆者は6.1.36をインストールした。

詳細は後述していく。

手順の詳細

1. Vagrant2.2.6をWSLにインストール

下記のコマンドでVagrant2.2.6をインストール。

sudo add-apt-repository ppa:tiagohillebrandt/vagrant
sudo apt install vagrant

Version 2.2.6は本記事執筆時点での最新バージョン。 古いVagrantを使っていると新しいバージョンのVirtualBoxに対応していない場合があるので、 適切なバージョンのVagrantをインストールしているかをチェックすること。

2. VirtualBox6.1.14以上をHost側にインストールする

下記のURLからVirualBox6.1.36をインストールする。

Oracle VM VirtualBox - ダウンロード| Oracle Technology Network | オラクル | Oracle 日本

バージョン6.1.14未満のVirtualBoxでは、WindowsのHyper-Vがオンになっていると VERR_NEM_MISSING_KERNEL_API_2のエラーが発生して起動できなかった。

一方で、WSL2はHyper-Vがオンになっていないと起動できないので、WSL2とVirtualBoxを同時に動かすことが出来なかった。

バージョン6.1.14でようやくこの問題が解決されて、WSL2とVirualBoxは同時に動かせるようになった。

ただし、VirtualBoxのバージョンを7以上にするとVagrantが動かなくなるので、6.1.36が望ましい。

詳細は下記URLに載っている。

3. VagrantがWSLからHostのVirtualBoxを呼び出せるように設定

WSL2のVagrantからHostのVirtualHostを使うには、いくつか設定が必要になる。

まずはWSL2の~/.bashrcに下記を追記する。

export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1"
export VAGRANT_WSL_WINDOWS_ACCESS_USER={Windowsのユーザー名}
export PATH="$PATH:/mnt/c/Program Files/Oracle/VirtualBox"
export PATH="$PATH:/mnt/c/Windows/System32/"
export PATH="$PATH:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/"
export VAGRANT_WSL_WINDOWS_ACCESS_USER_HOME_PATH="/mnt/c/vagrant/"

VAGRANT_WSL_ENABLE_WINDOWS_ACCESSを設定することでVagrantがWSLからHost側へのアクセスを可能になる。

VAGRANT_WSL_WINDOWS_ACCESS_USERはHost側のユーザー名を指定すること。

また、vagrant upをする際にVagrantはHost側のVirtualBoxとPowerShellを見つけることができないので、 Host側のVirtualBoxとPowerShellのPATHを追加する必要がある。

今回は/mnt/c/vagrant/のディレクトリを作成して、このディレクトリからvagrantを実行しようとしている。

Vagrantの設定の詳細は公式サイトに載っている。

5. VagrantがVirtualBox6.1を使えるように設定

筆者の環境では、デフォルトではVagrantはVirtualBoxの6.0までしか使えないので、 Vagrantの設定をいじることでVirtualBoxの6.1を使えるようにする必要がある。

そのためにも、まずは /opt/vagrant/embedded/gems/2.2.6/gems/vagrant-2.2.6/plugins/providers/virtualbox/driver/meta.rb のファイルを開き、下記の通りに修正する。

@logger.debug("Finding driver for VirtualBox version: #{@@version}")
 driver_map   = {
  "4.0" => Version_4_0,
  "4.1" => Version_4_1,
  "4.2" => Version_4_2,
  "4.3" => Version_4_3,
  "5.0" => Version_5_0,
  "5.1" => Version_5_1,
  "5.2" => Version_5_2,
  "6.0" => Version_6_0,
  "6.1" => Version_6_1, #これを追加
 }

そして /opt/vagrant/embedded/gems/2.2.6/gems/vagrant-2.2.6/plugins/providers/virtualbox/driver/version_6_1.rb のファイルを新たに作成して、下記の記述を追加。

require File.expand_path("../version_6_0", __FILE__)

module VagrantPlugins
  module ProviderVirtualBox
    module Driver
      # Driver for VirtualBox 6.1.x
      class Version_6_1 < Version_6_0
        def initialize(uuid)
          super

          @logger = Log4r::Logger.new("vagrant::provider::virtualbox_6_1")
        end
      end
    end
  end
end

最後に /opt/vagrant/embedded/gems/2.2.6/gems/vagrant-2.2.6/plugins/providers/virtualbox/plugin.rb を開き、下記のコードを追加する。

# Drop some autoloads in here to optimize the performance of loading
# our drivers only when they are needed.
module Driver
  autoload :Meta, File.expand_path("../driver/meta", __FILE__)
  autoload :Version_4_0, File.expand_path("../driver/version_4_0", __FILE__)
  autoload :Version_4_1, File.expand_path("../driver/version_4_1", __FILE__)
  autoload :Version_4_2, File.expand_path("../driver/version_4_2", __FILE__)
  autoload :Version_4_3, File.expand_path("../driver/version_4_3", __FILE__)
  autoload :Version_5_0, File.expand_path("../driver/version_5_0", __FILE__)
  autoload :Version_5_1, File.expand_path("../driver/version_5_1", __FILE__)
  autoload :Version_5_2, File.expand_path("../driver/version_5_2", __FILE__)
  autoload :Version_6_0, File.expand_path("../driver/version_6_0", __FILE__)
  autoload :Version_6_1, File.expand_path("../driver/version_6_1", __FILE__) #これを追加
end

以上の手順はOracleの公式ブログが紹介している手順であり、以下のURLに詳しく載っている。

4. virtualbox_WSL2をインストール

Vagrantの設定後はvirtualbox_WSL2と言うVagrantのプラグインをインストールする。 このプラグインはWSL2上からvagrant upvagrant sshを実行するためのもの。

vagrant plugin install virtualbox_WSL2

5. VagrantFileを作成する

WSL2から/mnt/c/vagrantに入り、vagrant init generic/ubuntu2004を実行する。そして、作成されたVagrantFileを 以下の様に修正する。

Vagrant.configure("2") do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://vagrantcloud.com/search.
  config.vm.box = "generic/ubuntu2004"
  config.vm.synced_folder ".", "/vagrant",disabled: true
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.customize [ "modifyvm", :id, "--uartmode1", "disconnected" ]
    vb.customize ["modifyvm", :id, "--nestedpaging", "off"]
    vb.customize ["modifyvm", :id, "--paravirtprovider", "hyperv"]
  end
end

6. Windowsを再起動する

主に、VirtualBoxのために再起動をする。

筆者の環境では、再起動をしないと下記のネットワーク関連でのエラーが発生していた。

Failed to open/create the internal network 'HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter

7. VagrantからVirtualBoxを起動&SSHでアクセス

ここまで来ると、以下のコマンドを実行するだけ。

vagrant up
vagrant ssh

vagrant upでVirtualBoxで動くVMを起動したり、SSH Keyを /mnt/c/vagrant/.vagrant.d/配下に設定し、vagrant sshでSSH接続でVMにログインできる。

万が一、何かしらのエラーが発生してシステムの設定を変更を行なった後は、以下のコマンドを実行すると良い。

vagrant reload
vagrant ssh

また、ssh vagrant等のコマンドでVirtualBoxのVMに入りたい場合は、以下のコマンドを実行すると良い。

vagrant ssh-config --host vagrant >> ~/.ssh/config

すると以下の様な~/.ssh/configの設定を出力してくれる。

Host vagrant
  HostName 172.26.16.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /mnt/c/vagrant/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL