VirtualBox+Vagrantによる、ローカル開発環境(Ansibleサーバ付)を構築する

※この記事の想定作業時間：**約1時間**

# 休日プログラミングを始めるために開発環境を構築する

休日プログラミングを始めるために、自分のPCにローカル開発環境を構築することにしましたので、そのときの記録です。
もちろん、社内のローカル開発環境にも使用できます。

# 最適な環境とは？-開発環境/ステージング環境/本番環境の違い-
一般的にクラウドサービスをリリースするまでに構築する環境は、大きく4パターンあります。

|           | ローカル開発環境 | インターネット開発環境(開発用/QA用) | ステージング環境 |本番環境|
|:---------|:-----------|:------------|:------------|:------------|
| **特徴** | 簡単な環境(環境を占有できる) | 商用を意識した環境 | ほぼ商用と同等の環境/リリース決定後のアプリ |商用で利用する環境| 
| **利用シーン** |プロト実装、リスク大の箇所の初期調査 | 結合テスト、リリース前の最後、インターネット環境でしか構築できないコンポの検証 | 運用手順をテストしたい |本稼働後| 
| **工程** | プロト | 開発(インフラ/アプリ)、結合テスト(アプリ/インフラ)、性能測定 | 運用テスト |本稼働後|
|**対象者**| 開発者 | 開発者/QA | 運用者/SREエンジニア | 運用者/SREエンジニア |
| **コスト** | 安い | 最小構成(開発)/QA(冗長化) | 高い(完全冗長化) |高い| 

会社では、開発環境用にチーム内予算からクラウドサービスを調達できるとは思いますが、基本的には何かしらの制約がかかるケースが多いと思います。
また、休日にプログラミングをするなら、自分でクラウドサービスを契約するとお金がかかります。そのため、お金のかからないローカル開発環境を構築することはメリットがあり、今回はその構築から始めます。

# （構成図）作成するローカル開発環境
今回構築しようと思う環境はざっくり以下のようなローカル開発用の環境です。

![Network Diagram (1).png](https://qiita-image-store.s3.amazonaws.com/0/166047/5f31ed5d-a488-d58a-f5d5-33bfb9d0cc20.png)
図は[cacoo](https://cacoo.com/)で作成しています。backlogというツールで有名なnulab(ヌーラボ)による描画ツールです。

GithubやDocker Hubは有償の部分もあるため、AnsibleサーバにGitlabやDocker registryを構築する選択肢を残したような想定です。

# ローカル開発環境を構築する
ここからはローカルPCに仮想環境を構築していきます。私はWin環境なので、Win環境に環境を構築することを想定します。

## VirtualBoxについて

VirtualBoxは、WindowsやMacなどのローカルPC内に仮想環境(linux,Solaris,Windows)を作ることができるソフトウェアです。類似のソフトウェアとしてはVMware Playerが挙げられますが、それぞれを比較してみます。
## VMware PlayerとVirtualBoxの比較
|           | 対応機種 | 商用利用 |特徴|
|:---------|:-----------|:------------|:------------|
| **VirtualBox** | Windows,Linux,mac,Solaris | 無償 | Vagrantの組み合わせによる、Infrastructure as codeのような構成管理が可能 |
| **VMware Player** | Windows,Linux | 有償 | GUIによる操作がしやすい |

結論としては、vagrantと組み合わせることで、VirtualBox一択と思われます。
特徴としては、VirtualBoxは社内でも無償なので利用しやすく、vagrantのようなツールで簡単に環境を構築/削除を行うことができます。削除を行っても、vagrantの冪等性により、同じ環境を再度構築ができるため、会社のPCのスペックに限界があっても、ある程度状況に応じてローカル環境のリソースも調節しやすいです。

## VirtualBoxをインストールする
[こちら](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html?ssSourceSiteId=otnjp)のサイトからDLしてきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/166047/67c6efc6-479e-39a3-3527-c7617bc199a0.png)

`Windows installer`をDLして、msiを実行してください。

## Vagrantをインストールする
VagrantもローカルPCにインストールします。
[こちら](https://www.vagrantup.com/downloads.html)のサイトからDLしてきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/166047/7f135a13-866b-de26-fe3a-287390a47296.png)


DLしてきたmsiをインストールしてください。

## Vagrantfileを作成する

インストールできたら、VMを構築していきます。
まずはコマンドプロンプトやGUIでvagrant用に空のファイルを作成してください。
デスクトップ配下など、どこでも良いと思います。

```
>mkdir vagrant
```
その後、作成したディレクトリに移動して、`vagrant init`を実行します。

```
>cd vagrant
>vagrant init
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
```

すると、ディレクトリ配下に`vagrantfile`が作成されていると思います。
そして、エディタ等で今回は以下のような内容に修正してください。

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

Vagrant.configure("2") do |config|
  config.vm.define :centos_1 do |centos_1|
    centos_1.vm.box = "bento/centos-7.2"
    centos_1.vm.network :private_network, ip: "192.168.0.1"
    
    # ansible install
    centos_1.vm.provision "shell",inline: $script
  end
  config.vm.define :ubuntu_1 do |ubuntu_1|
    ubuntu_1.vm.box = "bento/ubuntu-14.04"
    ubuntu_1.vm.network :private_network, ip: "192.168.0.2"
  end 
  config.vm.define :ubuntu_2 do |ubuntu_2|
    ubuntu_2.vm.network :private_network, ip: "192.168.0.3"
    ubuntu_2.vm.box = "bento/ubuntu-14.04"
  end 
  config.vm.define :ubuntu_3 do |ubuntu_3|
    ubuntu_3.vm.network :private_network, ip: "192.168.0.4"
    ubuntu_3.vm.box = "bento/ubuntu-14.04"
  end
end

$script = <<SCRIPT
  yum -y install epel-release
  yum -y install ansible --enablerepo=epel
SCRIPT
```

上記は、4台のVMを作成するvagrantfileになっています。
1台目はCentOSであり、作成後にAnsibleをインストールするようにしています。
vagrantでは、boxと呼ばれるファイルをDLしてくることにより、インストールするOSを選択することになります。
OSにも様々なものがありますが、`bento/XXXXX`というboxは、構成管理ツールChef社が提供しているboxであり、安心できるため、今回はそれを指定しています。

そして、vagrantfileを修正できたら、VMを作成していきます。
## VMを作成/起動する

下記のコマンドは、vagrantfileの内容に基づき環境を作成し、起動します。

```
>vagrant up
```

時間がかかるため、気長に待ちます。
作成できたら、VirtualBoxの画面で確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/166047/824b8a98-2dd2-2e5d-33d1-e59d9313f634.png)


## WinSCPでVagrant環境にログインする
VMが作成できていることが確認できたら、WinSCPでログインします。
まずは、VMへのログイン情報を確認します。
以下のコマンドを実行し、VMのidを取得します

```
>vagrant global-status
id       name     provider   state   directory
-------------------------------------------------------------------------
c1cd34c  centos_1 virtualbox running XXXXXXXXXXXXXXXXXXXXXXX
e2a0a47  ubuntu_1 virtualbox running XXXXXXXXXXXXXXXXXXXXXXX
60445d1  ubuntu_2 virtualbox running XXXXXXXXXXXXXXXXXXXXXXX
4d560f3  ubuntu_3 virtualbox running XXXXXXXXXXXXXXXXXXXXXXX
```

その後、以下のコマンドにより、ログインに必要な情報を取得します。

```
>vagrant ssh-config c1cd34c
Host centos_1
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile XXXXXXXXXXXXXXXXXXXXXXX/vagrant/.vagrant/machines/centos_1/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL
```
必要な情報がわかったので、WinSCPからログインを試みます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/166047/b5ceac86-446a-6a85-45fe-a01e62cf71f0.png)

[設定]から、秘密鍵の設定をこんな感じにします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/166047/1103f866-968c-3af5-2deb-544839830b45.png)

`秘密鍵OpenSSHをPUTTY形式に変換しますか？`
と表示されるので、変換します。

## TeratermからVagrant環境にログインする
WinSCPの時と同様です。鍵はWinSCPのログイン時に作成したputty形式のものを使ってしまいます。

## VMを停止する
作成したVMを停止します

```
>vagrant halt
```

## VMを削除する
作成したVMを削除します

```
>vagrant destroy
```

## トラブルシューティング：VMの作成時にAnsibleをうまく作成出来なかった場合
もし、ansibleの作成に失敗した場合は以下のコマンドを実行します。

```
>vagrant up --provision
```
provisionの部分は、初回起動時しか実行されないためです。

# まとめ
今回は、休日に最も手っ取り早くローカル開発環境を構築するために、VagrantとVirtualBoxを用いて、Ansibleサーバと、開発サーバ3台を作成し、SSHログインするところまで行いました。
何か不明点ありましたらコメントいただけたら改善検討したいと考えていますので、よろしくお願いします。