Mac + VirtualBox + VagrantでUbuntu環境を自動構築する。

# はじめに
Ansibleの動作確認などにおいて仮想環境を何度も作り直す必要がある。
このような場合、VirtualBoxとVagrantを併用すると非常に楽に対象の環境を再構築することが可能である。
今回はタイトルの通り、`Mac + VirtualBox + Vagrant`でUbuntuを何度も再構築可能な環境の構築方法について備忘録としてまとめていく。少しでも他の誰かの役に立つと嬉しい。

# バージョン情報
* MacOS: 10.14.2(Mojave)
* VirtualBox: 5.2.26
* Vagrant: 2.2.3

# そもそも・・・
* 前提知識を超簡単に説明しておく。

## VirtualBoxとは？
* ホストOS型仮想化アプリケーションの大定番。
* インストールが簡単で動作も軽い(個人の感想です。)

## Vagrantとは？
* 仮想環境の構成管理ツール
* VirtualBoxとの連携が可能

# VirtualBoxのインストール
* 下記ページから該当のインストーラを入手し、インストールを行う。
    * https://www.virtualbox.org/wiki/Downloads
    * 基本的にそのままの設定で問題ないが、データディレクトリなどこだわりがあれば都度設定しておく。

# Vagrantのインストール
* 下記ページから該当のインストーラを入手する。
    * https://www.vagrantup.com/downloads.html
* インストール後はvagrant用に作業ディレクトリを作成しておく。
    * 私の場合は`VirtualBox VMs`の下に`vagrant`という作業フォルダを作成し、そこで作業をしている。
* 次に作業ディレクトリに移動し、以下コマンドを実行しvagrantの利用準備を終える。

```
vagrant init
```

# 構成管理ファイルの作成: VagrantFile
* vagrantで行う構成管理では、`VagrantFile`と呼ばれるファイルを利用して構成の管理を行う。
* 構成管理を行う対象の端末についての設定を入れたり、設定したスクリプトを実行したりできる。
* 複数の仮想端末の構成管理を1つのファイルで行うことが可能。
* `VagrantFile`自体はvagrantインストール時点で最後に行なった`vagrant init`により作成される。
* 私が使っているものを例として上げる。

```
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.define :vm01 do |vm01|
    vm01.vm.box = "bento/ubuntu-18.04"
    vm01.vm.hostname = 'vagrant-vm01'
    vm01.vm.network "public_network", bridge: 'en0: Wi-Fi (AirPort)', ip: "x.x.x.x"
    vm01.ssh.insert_key=false
    vm01.vm.box_check_update = false
    vm01.vm.provision :shell, inline: $script
    vm01.vm.provider "virtualbox" do |v|
         v.customize ["modifyvm", :id, "--memory", 2048, "--cpus", "1", "--ioapic", "off"]
    end
    vm01.vm.provision "file", source: "[file src path]", destination: "[file dst path]"
  end

  config.vm.define :vm02 do |vm02|
    vm02.vm.box = "bento/ubuntu-18.04"
    vm02.vm.hostname = '[hostname]'
    vm02.vm.network "public_network", bridge: 'en0: Wi-Fi (AirPort)', ip: "x.x.x.x"
    vm02.ssh.insert_key=false
    vm02.vm.box_check_update = false
    vm02.vm.provision :shell, inline: $script
    vm02.vm.provider "virtualbox" do |v|
         v.customize ["modifyvm", :id, "--memory", 2048, "--cpus", "1", "--ioapic", "off"]
    end
    vm02.vm.provision "file", source: "[file src path]", destination: "file dst path"
  end
end

$script = <<END
apt-get update
apt-get install -y python-pip python-apt
END
```

* 上記の構成管理ファイルで行なっていることまとめ。
    * 2台の仮想マシンの構築
        * 2台ともホスト名、IP以外は同じ内容。
    * box(仮想マシンの元となるイメージ)(=vm01.vm.box): `bento/ubuntu-18.04`
        * bentoが提供するイメージが一番クリーンなものと言われているので利用している。
    * ネットワーク設定(=vm01.vm.network): パブリックネットワーク、ホストマシンのwifiアダプタからのブリッジ接続、ip指定。
    * (vm01.ssh.insert_key)
    * アップデートのチェック(=vm01.vm.box_check_update): なし
        * 毎回同じ仮想マシンが構築されることを必要としていたから。
    * 構築後にシェルを実行(=vm01.vm.provision :shell)
        * 最下部で定義しているシェルスクリプトを実行している。
        * 今回はapt-getのアップデートとpythonライブラリのインストールをやらせていた。
    * 仮想マシンのスペック等(=vm01.vm.provider): virtualboxでの構築。メモリなども指定している。
    * 構築後のファイル転送(=vm01.vm.provision "file")を行なっている。


# 構築
* `VagrantFile`が格納されているディレクトリにおいて以下のコマンドを実行することで構築が始まる。
* 1つのVagrantFileに複数の仮想マシンの構成情報が記載されている場合は以下のコマンドで複数の仮想マシンの構築が順番に行われる。

```
vagrant up
```

# 接続
* 構築した仮想マシンに接続するには`VagrantFileがあるディレクトリにおいて以下コマンドを実行する。

```
vagrant ssh
```

* 1つのVagrantFileで複数の仮想マシンを構築している場合は、上記コマンドの後にホスト名を付与する必要がある。(=config.vm.hostname)

```
vagrant ssh [hostname]
```


# 削除
* `VagrantFileがあるディレクトリにおいて`以下のコマンドを実行することにより、そのVagrantFileで構築した仮想マシンを削除することが可能。
* 対象のVagrantFileで複数の仮想マシンが構築されている場合、全て削除される。
    * 個別に削除するには最後に仮想マシン名を与える(=config.vm.hostname)

```
vagrant destroy
```

もしくは

```
vagrant destroy [hostname]
```

# まとめ & 感想
* AnsibleのPlaybookを作成するときなど何度も同じ仮想マシンを再構築するような際には非常に便利。
* virtual box + vagrantの利用環境を整えるのもそんなに時間がかからず良い。
* 2台の仮想マシン構築が2, 3分で完了するためかなり早い。(ネットワークなどの状況によるが・・・。)