備忘録 Vagrantfile を書く

# Vagrantfile を書くところでハマった
自宅の Mac OS 上で Vagrant を動かしたいと思ったため、1からVagrantfileを書きます。
特殊なオプションは利用せず、Vagrantfileのコメントと公式のドキュメントをみながら作成します。
Vagrant のバージョンは 2.2.6 を利用します。

## 要約
 - vagrant init で作成される Vagrantfile のコメントだけではなく、Vagrant の公式のドキュメントを読みましょう
 - vagrant up した時にエラーメッセージが表示される場合は、Vagrant の公式のドキュメントを読んで対応しましょう
 - url の指定と SSL 証明書の扱いについては指定する
 - Shellの部分はタイムアウトが発生しないように作り込む

## Vagrantfile の作り込み
### Vagrantfile を作る
おもむろに Vagrant init を実施します。

```bash:
$ vagrant init
$ ls
Vagrantfile
```
### Vagrantfile を Visual Studio Code で開く
Vagrantfile を VS code で開きます。
Vagrant の EXTENSIONS を入れておくと Vagrantfile に色が付いて幸せになります。
![スクリーンショット 2019-12-25 15.09.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/5d21abf3-a971-a7c1-fc3f-07ab0d96cff0.png)

### Vagrantfile に書かれてあるコメントを読みます
雑に翻訳すると以下の通り。

 - 前提に関する説明事項
    - Vagrant.configure("2") do |config| の中に設定を書いてください
    - "2" はコンフィグのバージョンなので変更しないでください
    - 標準的なコンフィグのオプションは下に示します
    - 完全なリファレンスは[オンラインマニュアル](https://docs.vagrantup.com.)を参照してください
 - 設定に関する説明事項
    - box の設定
      - 全ての Vagrant 環境は box を必要とします
      - box は https://vagrantcloud.com/search で検索できます
    - box の自動アップデートの無効
      - box を自動的にアップデートのチェックを無効にできます
      - その場合は、ユーザーがアップデートのためにコマンドを走らせたときにのみチェックされます
      - この推奨されません
   - ポートフォワーディングの設定
     - ホストマシンの 8080 番ポートをゲストマシンの 80 番ポートに割り当てる（パブリックからアクセス可）  
       config.vm.network "forwarded_port", guest: 80, host: 8080
     - ホストマシンの 8080 番ポートをゲストマシンの 80 番ポートに割り当てる（127.0.0.1のみアクセス可）   
       config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
   - ネットワークの設定
     - プライベートネットワークを作成する（ホストマシンからのみ接続可能）  
       config.vm.network "private_network", ip: "192.168.33.10"
     - パブリックネットワークを作成する（ホストマシン上の別のネットワークとして表示される）  
       config.vm.network "public_network"
   - ゲスト VM に追加のフォルダをシェアする設定
     - 1つ目の変数は、ホストマシンの実際のパスです
     - 2つ目の変数は、ゲスト VM にマウントするフォルダのパスです
     - オプションの3つ目の変数は、必須ではありません
   - Provider-specific の設定(boxを提供しているプロバイダごとの微調整）
     - virtualbox を利用する場合、GUIの利用やメモリサイズの指定ができる
     - 利用できるオプションは[ドキュメント](https://www.vagrantup.com/docs/virtualbox/configuration.html)を参照してください
   - シェルスクリプトを使ったプロビジョニングが可能。
   - Puppet,Chef,Ansible,Salt,Docker なども可能。

### 構成
Python のコードを書いて、Crontab で定期実行するような仕組みを作りたいため、今回は以下のような構成にします。
VMの上にDockerを載せるか微妙に悩みました。

 - 設定ファイルのバージョンは2を利用する
 - box は VirtualBox を利用する
 - 自動アップデートは無効にしない
 - ポートフォワーディングは設定しない
 - プライベートネットワークのみ設定する（IPアドレスは192.168.1.100を利用）
 - VM に追加フォルダはマウントしない
 - Provider-spcific にはメモリサイズのみ(1.0GB)記載する
 - yum で Python3 と pip をインストール
 - pip で必要なライブラリをインストール

### Vagrantfile の作成（1回目）
最初に最低限の項目を入れた Vagrantfile を作って vagrant up を実行しました。

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

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "192.168.1.100"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
  end
  
  config.vm.provision "shell", inline: <<-SHELL
    yum update
  SHELL
end
```
vagrant up するとエラーが発生しました。
![スクリーンショット 2019-12-25 22.36.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/3fadf93a-7a10-c58e-57dd-a49a0b06686c.png)
「box が vagrantcloud.com に存在しない」と「ssl 証明書に問題がある」の2つの問題を抱えているようです。

### Vagrantfile の作成（2回目）
公式のドキュメントを読むと、以下の2つの設定を追加すれば回避できそうなことがわかりました。

 - 追加
   - config.vm.box_url = "https://app.vagrantup.com/centos/boxes/7"
   - config.vm.box_download_insecure = true

![スクリーンショット 2019-12-26 20.30.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/2ee5bbfb-2fa6-659b-83e4-485d478ffd64.png)

今度こそいったか？と思いきや、再びエラーが発生しました。
![スクリーンショット 2019-12-26 20.38.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/4f1cc8c6-82c8-9cc9-9932-4aa1c894a640.png)

### Vagrantfile の作成（3回目）
yum update で、yかnの入力待ちをし、タイムアウトしてしまったではないかと推測しました。
config.vm.provision の中のコマンドを sudo yum update -y に変更し、vagrant up を実行します。
![スクリーンショット 2019-12-26 22.26.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/405088b4-2423-5dbc-a08e-38a7728cba09.png)

うまくいきました。
vagrant status で確認し、起動していることを確認します。
![スクリーンショット 2019-12-26 22.27.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/70d3af6a-7c9a-f419-82be-d5a10b5b1769.png)

### Vagrantfile の作成（4回目）
今のままでは、

 - hostname が指定されておらず default の名前が与えられている
 - 複数の仮想マシンを動かせない
 - Python3 と必要なライブラリが入っていない

状態のため、これらを修正していきます。

```ruby:Vagfantfile(修正前）
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.box_url = "https://app.vagrantup.com/centos/boxes/7"
  config.vm.box_download_insecure = true
  config.vm.network "private_network", ip: "192.168.1.100"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
  end

  config.vm.provision "shell", inline: <<-SHELL
    sudo yum update -y
  SHELL
end
```

 - 追加
   - [hostname の指定](https://www.vagrantup.com/docs/vagrantfile/machine_settings.html#config-vm-hostname)
     - config.vm.hosname = "hogefuga" で指定
   - [複数の仮想マシンを動かす指定](https://www.vagrantup.com/docs/multi-machine/)
     - config.vm.define "xxx" do |yyy| で指定が可能
   - Python3 と pip のインストール
     - これは通常の CentOS に Python3 を導入する手順と同じ

```ruby:Vagrantfile(修正後)
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.define "aqua-konosuba" do |py|
    py.vm.box = "centos/7"
    py.vm.box_url = "https://app.vagrantup.com/centos/boxes/7"

    py.vm.box_download_insecure = true
    py.vm.network "private_network", ip: "192.168.1.100"
    py.vm.hostname = "aqua-konosuba"

    py.vm.provider "virtualbox" do |vb|
      vb.memory = "1024"
    end

    py.vm.provision "shell", inline: <<-SHELL
      sudo yum update -y
      sudo yum install python3 -y
      sudo pip3 install requests qrcode pillow pyyaml
    SHELL
  end
end
```
vagrant up を実行します。

![スクリーンショット 2019-12-27 14.09.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/767d3090-71dc-d075-3668-50e1bc67a345.png)

![スクリーンショット 2019-12-27 14.09.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/38b96c54-c431-a396-a4bc-eeaa5949b9f2.png)

![スクリーンショット 2019-12-27 14.19.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54900/cc0625e0-3229-1ec7-0898-e628801ba8ea.png)

うまくいきました。必要としていた、Vagrantfile はできました。

## おわりに
何もわからない状態から Vagrantfile を書くことを今回は行いました。
着手から1週間ぐらいでコツコツやれば、雑に使うぐらいには理解できそうです。

## よく分からなかった点
 - VS code の拡張機能はどこまで信用していいものか
 - Provider-specific のコメントの英文  
   Provider-specific configuration so you can fine-tune various backing providers for Vagrant.
 - なぜ URL の指定がないとだめだったのか
 - SSLの証明書を適切に扱うにはどうしたらよかったのか
 - MultiMachine の設定は本当にこれでよかったのか

## 参考文献
[Vagrantfile - Machine Setting](https://www.vagrantup.com/docs/vagrantfile/machine_settings.html)
[Vagrantfile - Multi Machine](https://www.vagrantup.com/docs/multi-machine/)
[Vagrant Atlasがいつの間にか無くなってたので移行した](https://qiita.com/tmiki/items/b69d460514afbffb245b)