もう VirtualBox の設定で悩まない。そう、Vagrant ならね😏

# しししし知っとったわ！！
[前の記事](https://qiita.com/hajime-f/items/ea34a38a405f48b1ce65)を読んだ弊社エンジニア
**「あれ？ 藤田さん、Vagrant 使わないんすか？」**

……というわけで、Vagrant という文明の利器を使って VirtualBox の環境を作りたいと思います。

- macOS Catalina 10.15.6（ホストOS）
- Ubuntu Server 20.04（ゲストOS）
- VirtualBox 6.1.14

# Vagrant ってなんすか？

ひとことで説明すると **「仮想環境を全自動でいい感じに仕上げてくれるツール」** らしい。詳しいことは知らん。

全自動とはいえゼロから仮想マシンをセットアップするのは大変なので、「box」と呼ばれる環境のテンプレートを利用します。この box は、[Vagrant Cloud](https://app.vagrantup.com/boxes/search) で探せるらしい。

私は Ubuntu Server 20.04 を使いたいので、今回は [peru/ubuntu-20.04-server-amd64](https://app.vagrantup.com/peru/boxes/ubuntu-20.04-server-amd64) を使わせてもらうことにしました。

ちなみに、Ubuntu Server 20.04 の Box は他にも公開されています。今回わざわざこれをセレクトしたのは、この Box を作っている peru が、[いい感じのV字に仕上がっている](https://app.vagrantup.com/peru)ところに好感を覚えたから。お互いがんばろうぜ、ブラザー。

# V字の勢いでインストールが終わる

そんな peru に敬意を表して、Vagrant を動かすディレクトリの名前を「peru」にした。あとは peru の直下で ```init``` して ```up``` するだけ。環境変数の設定を忘れずにね！

```
$ mkdir peru
$ cd peru
$ vagrant init peru/ubuntu-20.04-server-amd64
$ export VAGRANT_DEFAULT_PROVIDER=virtualbox
$ vagrant up
```

すると、VirtualBox が起動したかと思えば、すごい勢いで画面にログが流れ始めた。peru のがんばりを頼もしく感じて、コーヒーを飲みに立って帰ってきたら全部終わってた。早すぎるやろ。

おもむろに ssh 接続を試みると、パスワード入力を求められることもなくスルリとログイン。

```
$ vagrant ssh
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-48-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Tue Sep 29 14:54:15 2020 from 10.0.2.2
vagrant@localhost:~$ 
```

手作業でインストールする途中で[「なんで？」とか言ってた頃](https://qiita.com/hajime-f/items/ea34a38a405f48b1ce65)を思い出すと、胸の熱さで肉が焼けそう。私が芋洗坂係長なら踊り出している（肉の前で）。

# peru をオレ流に染める

[前にも書いた](https://qiita.com/hajime-f/items/2c10db500bc40d1f8e29)ように、私はホスト名に南の島の名前を付けると決めています。なので、peru 直下にある Vagrantfile を編集し、まずホスト名を「tonga」にします。ついでに VM 名も「tonga」にしておこう。

```ruby:Vagrantfile
  config.vm.define "tonga"
  config.vm.hostname = "tonga"
  config.vm.provider :virtualbox do |vb|
    vb.name = "tonga_ubuntu-server-20.04.1"
  end
```

次に、SSH 接続するユーザを変更します。Linux での私のユーザ名は、20年以上前から「hajime-f」と決まっている。

ユーザ「vagrant」のまま tonga に SSH 接続し、まずはユーザ「hajime-f」を追加します。

```bash
$ vagrant up --provision
$ vagrant ssh
...
vagrant@tonga:~$ sudo useradd -m -s /usr/bin/bash -U hajime-f
vagrant@tonga:~$ sudo passwd hajime-f
```

**いま……私は……ものすごく懐かしいコマンドを叩いている…！**
おっさんのノスタルジアを著しく刺激されて嗚咽が漏れる。いつぶりだよこのコマンド。

次に、```/etc/sudoers``` を編集し、hajime-f にスーパユーザの全権限を持たせます。

```
vagrant@tonga:~$ sudo visudo
・・・
# User privilege specification
root    ALL=(ALL:ALL) ALL
hajime-f        ALL=(ALL) NOPASSWD: ALL
```

この ```visudo``` にも胸を撃ち抜かれました。忘れてたわこんなコマンド。

ちなみに、```NOPASSWD``` を付けるのは、Vagrant のコマンドをエラーなく動かすためらしい。詳しいことは知らん。セキュリティ的にアレですが、ここはしゃあない。

さらに、ホスト OS の公開鍵を hajime-f にセットします。ホストの端末に ```~/.ssh/id_rsa.pub``` を表示させておいて、ゲストの ```~/.ssh/authorized_keys``` にコピペします。

```bash
vagrant@tonga:~$ sudo su hajime-f
・・・
hajime-f@tonga:~$ mkdir ~/.ssh
hajime-f@tonga:~$ vi ~/.ssh/authorized_keys ## → ホストの公開鍵の中身をコピペ
hajime-f@tonga:~$ chmod 600 ~/.ssh/authorized_keys
```

ここまで設定して、とりあえず tonga がきちんと停止するかを確認。

```bash
$ vagrant halt 
```

よーしよしよし、いい子だ（ムツゴロウさん的に）。

# tonga がおっきしない問題

ここまでゲストを設定すれば、あとは Vagrantfile にユーザ名と SSH の秘密鍵の場所を設定するだけ。

```ruby:Vagrantfile
config.ssh.username = "hajime-f"
config.ssh.private_key_path = "/Users/hajime-f/.ssh/id_rsa"
```

これで完了！
いざ！尋常に vagrant up！

```
$ vagrant up --provision
・・・
==> tonga (Ubuntu Server 20.04.1): Booting VM...
==> tonga (Ubuntu Server 20.04.1): Waiting for machine to boot. This may take a few minutes...
    tonga (Ubuntu Server 20.04.1): SSH address: 127.0.0.1:2222
    tonga (Ubuntu Server 20.04.1): SSH username: hajime-f
    tonga (Ubuntu Server 20.04.1): SSH auth method: private key
dyld: lazy symbol binding failed: Symbol not found: _SHA512Init
  Referenced from: /opt/vagrant/embedded/gems/2.2.10/gems/bcrypt_pbkdf-1.0.1/lib/bcrypt_pbkdf_ext.bundle
  Expected in: flat namespace

dyld: Symbol not found: _SHA512Init
  Referenced from: /opt/vagrant/embedded/gems/2.2.10/gems/bcrypt_pbkdf-1.0.1/lib/bcrypt_pbkdf_ext.bundle
  Expected in: flat namespace
```

あ……あれ？？
**tonga がおっきしない……**

いや、正確に言えば、VirtualBox 自体は起動するし、```$ vagrant ssh``` を叩けば、ユーザ「hajime-f」で tonga にログインできる。

とはいえ、起動時に妙なエラーが表示されるし、```$ vagrant halt``` を叩いても同じエラーで tonga が停止しない。それは困る。

エラーをよく見ると、どうやら何かのライブラリが秘密鍵の復号に失敗しているらしい。

ここで結構ハマったのですが、いろいろ調べているうちに、単純に ```ssh-add``` していないことに思い至って残機が１つ減った。エンジニアリングから 10 年以上も遠ざかっているブランクを、このあたりで思い知る。

```bash
$ ssh-add ~/.ssh/id_rsa
$ vagrant up
```

**無事におっき完了。**
よーしよしよし、いい子だ（ムツゴロウさん的に）。

# あとは適当に設定

ユーザ「hajime-f」で tonga が正常に動いたので、ユーザ「vagrant」を削除します。ユーザ名とパスワードが「vagrant / vagrant」だなんて、セキュリティがガバガバで気持ち悪いから。

```
hajime-f@tonga:~$ sudo userdel -r vagrant
```

次に、ホストの 8080 番ポートをゲストの 80 番ポートに繋げるように、ポートフォワーディングを設定します。これで Web アプリ作りまくれるぜ！

```ruby:Vagrantfile
config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
```

さらに、ディレクトリ共有の設定をします。ホスト側のディレクトリは、Vagrantfile からの相対パスであることに注意。

```ruby:Vagrantfile
config.vm.synced_folder "../Development", "/vagrant_data"
```

# bali を追加

使っているうちに、tonga だけでは物足りなくなってきたので、ホスト名「bali」という仮想マシンを新たに追加します。複数台の運用だ！ガハハ！

結果として、次のような Vagrantfile になりました。

```ruby:Vagrantfile
Vagrant.configure("2") do |config|

  config.vm.box = "peru/ubuntu-20.04-server-amd64"

  # tonga の設定
  config.vm.define "tonga" do |tonga|
    tonga.vm.hostname = "tonga"
    tonga.vm.provider :virtualbox do |vb|
      vb.name = "tonga_ubuntu-server-20.04.1"
    end
    tonga.vm.network :forwarded_port, id: "https", guest: 80, host: 8080, host_ip: "127.0.0.1"
    tonga.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2222, host_ip: "127.0.0.1"
  end

  # bali の設定
  config.vm.define "bali" do |bali|
    bali.vm.hostname = "bali"
    bali.vm.provider :virtualbox do |vb|
      vb.name = "bali_ubuntu-server-20.04.1"
    end
    bali.vm.network :forwarded_port, id: "https", guest: 80, host: 8081, host_ip: "127.0.0.1"
    bali.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2223, host_ip: "127.0.0.1"
  end

  config.ssh.username = "hajime-f"
  config.ssh.private_key_path = "/Users/hajime-f/.ssh/id_rsa"
  config.vm.synced_folder "../Development", "/vagrant_data"

end
```

tonga だけを起動したければ、```$ vagrant up tonga```、bali だけを停止させたければ、```$ vagrant halt bali``` でオーケー。

# peru よ、さらば
ここまで設定して思ったのですが、ホームディレクトリを一覧したとき、**謎の「peru」が目に入るのがどうも気に入らない**。誰だよお前。

というわけで、「peru」を普通に「VirtualBox」に変更しちゃった。

さよなら peru。君のことは忘れないよ。

```
$ cd ~
$ mv peru VirtualBox
```

続く……[「Ubuntu Server 20.04 に Docker をインストールする」](https://qiita.com/hajime-f/items/2bd1cad93d3ae4a62be8)

# 追記：自分用のメモ

```zsh:~/.zshrc
# zsh-completions(補完機能)の設定
if [ -e /usr/local/share/zsh-completions ]; then
            fpath=(/usr/local/share/zsh-completions $fpath)
fi
autoload -U compinit
compinit -u

PROMPT='[%n@%F{cyan}%\%m:%F{white}%\%1~]$ '

umask 022

alias h='ls -lLhG --color'
alias ha='ls -lhaHLG --color'
alias df='df -h'
alias cd='pushd'
alias p='popd'
alias cp='cp -r'
alias python='python3'
alias vi='vim'

setopt share_history
setopt hist_ignore_all_dups
setopt hist_ignore_space
setopt hist_reduce_blanks
setopt extended_glob
setopt correct

export TERM=xterm-256color
autoload -Uz compinit && compinit
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
```