Vagrantで仮想マシンを管理する

# 個人的にVagrantが便利だと思う点

要約すると、VirtualBoxで一つ一つ手作業で行なっていたことをコードで一括実行できるのでラク。

- 仮想マシンの作成や設定をコードで管理することができる
- OSのイメージをダウンロードする手間が省ける
- SSHの公開鍵認証方式の構築まで実施してくれる
- ansibleなどの構成管理まで呼び出すことができる

今回は、vagrantで、CentOS７の仮想マシンを作成・構築・起動するまでをまとめた。
また、Tipsとして起動と同時にansibleで構成管理を行う方法も記載している。

# インストール

HashiCorpの[Download Vagrant](https://www.vagrantup.com/downloads.html)から、ダウンロードしインストールする。

macでhomebrewを利用している場合なら、homebrew-caskでもインストールできる。
`brew cask install vagrant`

# vagrantの初期化

クライアントPCの所定フォルダに移動しvagrantを実行するための初期化を行う。

```
vagrant init
```

実行するとvagrantfileが作られ、vagrantで仮想マシンを構築するためのルートフォルダとなる。

# vagrantfileの編集

作成されたvagrantfileを開くと、サンプル設定が記述されてい流ので、これを元に設定を編集することもできる。
今回は以下のように上書きしてしまう。

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

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.hostname = "centos"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "4096"
    vb.cpus = 2
  end
end
```

記述内容は以下の通り。

`config.vm.box`
OSイメージの指定
上記は、HasiCorp社のCentOS７を使用している

`config.vm.hostname`
仮想マシンのホスト名

`config.vm.network`
仮想マシンのネットワーク設定
"private_network"とすると、"アダプタ１：NAT、アダプタ２：ホストオンリーアダプター"と同義となる。
`ip:`で、仮想マシンのipアドレスも指定できる。

`config.vm.provider`
仮想マシンの各種設定
`"virtualbox" do |'x'|` の'x'は、設定内における仮想マシンの変数名となる。

- x.memoryはゲストOSに割り当てるメモリ
- x.cpusはゲストOSに割り当てるCPUコア数

# vagrantの実行コマンド

カレントディレクトリをvagrantfileが置いてある場所にして実行する

`vagrant up`
vagrantfileを基に仮想マシンを生成し、起動する。
-- provisionオプションを付けて実行すると、 仮想マシン作成後にvagrantfileで編集した内容で再設定（プロビジョニング）する。

`vagrant halt`
仮想マシンを停止する

`vagrant reload`
仮想マシンを再起動する。(つまり、reload -> up)

`vagrant destroy`
仮想マシンを停止し削除する。

`vagrant box update`
仮想マシンのベースを更新する。
仮想マシンは一度起動したら自動Updateは行わないので、更新したければ手動で実行する。

# 構築した仮想マシンに接続する

```
vagrant ssh
```

- vagrantで作成した仮想マシンには、`vagrant`ユーザーが作られ、このユーザーで接続する。
- パスワードはvagrantもrootも`vagrant`で変更しない [^1]
- Vagrantで立ち上げた仮想マシンには自動的にキーペアが作られ、公開鍵暗号方式でssh接続される[^2]

# Tips

## ローカルPCのファイルを仮想マシンで共有する

[このページ][link2]を参考に設定した。

Vagrantのプラグインvagrant-vbguestをインストールする

```
vagrant plugin install vagrant-vbguest
```

vagrantfile に以下の設定を入力しローカルPCのファイルを共有する。

```
config.vm.synced_folder [ローカルPCのディレクトリパス],[仮想マシンのディレクトリパス],:mount_options => ['dmode=775','fmode=664']
```

## 仮想マシンにansibleをインストールし、実行する

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

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.hostname = "centos"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "4096"
    vb.cpus = "2"
  end

  # ローカルPCのplaybookを仮想マシンで共有する
  config.vm.synced_folder "playbook","/home/vagrant/playbook",:mount_options => ['dmode=775','fmode=664']

　　　　# shellスクリプト実行
  config.vm.provision "shell", inline: $script
end

# shellスクリプト
$script = <<END

  # 仮想マシンにansibleがインストールされていなければインストール
  if ! [`which ansible`]; then
    yum -y install epel-release
    yum -y install ansible
  fi

  # 仮想マシンに共有されたancible-playbookでansibleを実行する
  ansible-playbook -i /home/vagrant/playbook/hosts-development /home/vagrant/playbook/site.yml
END
```

## proxy環境下でVagrantから仮想マシンを構築する場合の注意事項

仮想マシンからyumなどでパッケージをダウンロードする時など、インターネットアクセスする際にproxyを超えられない場合は以下の設定を行ってみる。

vagrantプラグイン vagrant-proxyconfをインストールする。　

```
vagrant plugin install vagrant-proxyconf
```

Vagrantfileに環境変数に設定したproxyを参照するように追加

```
config.proxy.http = [PROXY_URL]
config.proxy.https = [PROXY_URL]

/**
PROXY_URLの設定例
http://[account]:[password]@[proxy-host]:[proxy-port]

Proxyがアカウント認証を行なっていれば、[account:password]を設定する。

ローカルPCの環境変数にPROXY_URLを作成しておけば 以下のように環境変数を参照できるので、vagrantfileにProxyの設定値を直接書く必要が無い。
config.proxy.http = ENV[PROXY_URL]
**/
```

これらを踏まえたvagrantfileへのProxy設定記入例

```
if Vagrant.has_plugin?("vagrant-proxyconf") && ENV['PROXY_URL']
  config.proxy.http = ENV['PROXY_URL']
  config.proxy.https = ENV['PROXY_URL']
end
```

## 仮想マシンにローカルPCが参照しているDNS設定を継承する

仮想マシンから名前解決できない場合に設定することよい。

``` 
config.vm.provider "virtualbox" do |vb|
  vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
end
```

# 参考

[Vagrant by HashiCorp](https://www.vagrantup.com/)
[【Vagrantドキュメント意訳】00.目次][link1]
[AnsibleをゲストOSに押し込んでVagrant環境構築する][link2]
[VAGRANTでANSIBLEを使うのはSSHの理解がカギ][link3]

[link1]:https://qiita.com/ringo0321/items/70384c0ec09d5a7c4c76
[link2]:https://qiita.com/progre/items/ccc2d8c2ec7ae8a4ed61
[link3]:http://kzlog.picoaccel.com/post-936/


[^1]: vagrantで仮想マシンを構築・起動する際に、root権限などを利用しているのでパスワードが変わると実行できなくなる場合がある。またSSHの公開鍵認証方式でクライアント(ホスト)から仮想マシンにアクセスすることを想定しているのでパスワード変更運用は不要と考える。

[^2]: vagrant upで立ち上げた後に vagrant ssh-config を見るとIdentityFileでクライアント側の秘密鍵の場所が確認できる。仮想環境側には ~/.ssh/authorized_keys に公開鍵が置かれる