Amazon Linux 2 boxファイル作成手順

## 1. 概要
開発時の動作確認用のために、Amazon Linux 2のboxファイルが欲しかったので作成手順をまとめてみました。利用環境・ツールはWindows10 Pro、Vagrant2.2.16、Virtual Box6.1.20r、Git Bashを使っています。
色々な方の記事を参考にやってみて何とかできたので、この場を借りてお礼申し上げます:relieved:

## 2. 作成手順
### 2.1 Virtual Boxのイメージをダウンロード
[Amazon Linux2の公式サイト](https://aws.amazon.com/jp/amazon-linux-2/)の「Amazon Linux 2 仮想マシンイメージ」より最新のVirtual Boxのイメージをダウンロードする。

```shell=
$ curl -LO https://cdn.amazonlinux.com/os-images/2.0.20210525.0/virtualbox/amzn2-virtualbox-2.0.20210617.0-x86_64.xfs.gpt.vdi
```

### 2.2 cloud init用データの作成
seedフォルダ内でmeta-data、user-dataファイルをそれぞれ作成する。
sshの公開鍵は[Vagrant 公開鍵・秘密鍵](https://github.com/hashicorp/vagrant/tree/master/keys)から持ってきている。
packages:～でVirtualBox Guest Additions のビルドに必要なパッケージをインストール、runcmd:～でrootパスワードがランダム変更されないようにしている（パスワードはvagrantで固定）。
**#cloud-configの#の前にスぺースは入らないので注意する。**

```shell=
$ mkdir seed
$ echo "local-hostname: localhost.localdomain" > seed/meta-data

$ cat << __EOF__ > seed/user-data
#cloud-config
users:
  - default 
  - name: vagrant
    groups: wheel
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    plain_text_passwd: vagrant
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key 
    lock_passwd: false

chpasswd:
  list: |
    root:vagrant
  expire: False

packages:
  - kernel-devel
  - kernel-headers
  - gcc
  - make
  - perl
  - bzip2
  - mod_ssl

runcmd:
  - sed -i 's/.*root:RANDOM/#&/g' /etc/cloud/cloud.cfg.d/99_onprem.cfg
__EOF__
```

### 2.3 ISOイメージの作成
Windows環境だと下記のコマンドが使えない。

```shell=
$ hdiutil makehybrid -iso -joliet -o seed.iso seed -joliet-volume-name cidata
```
そのため、[Windows10 で Amazon Linux 2 を vagrant で動かすまで](https://qiita.com/tutida/items/22e02766150790bc90be)を参考に、
[isocreater](https://sourceforge.net/projects/iso-creator-cs/?source=typ_redirect)を利用して、seed.isoファイルを作成する。

### 2.4 VMの起動
1. VBoxManageコマンドでVirtual Box上のVMをコマンドラインから起動する。VBoxManageコマンドを実行して見つからない場合、[パスを通す手順](http://realize.jounin.jp/path.html)を参考にパスを通す。デフォルトでVirtual Boxをインストールしている場合は下記のパスになるので、それを設定する。

```
C:\Program Files\Oracle\VirtualBox
```
2. Git Bash for windowsを起動してダウンロードしてきたVirtual Boxのイメージやseed.isoファイルを指定し、VMを起動する。

```shell=
# Virtual Boxのイメージやseed.isoファイルが直下にあるか確認
$ ls -al

$ VM=vagrant-amznlinux2

# ダウンロードしたVirtual Boxのイメージを指定
$ VDI=amzn2-virtualbox-2.0.20210617.0-x86_64.xfs.gpt.vdi

$ VBoxManage createvm --name "$VM" --ostype "RedHat_64" --register

$ VBoxManage storagectl "$VM" --name "SATA Controller" --add "sata" --controller "IntelAHCI"

$ VBoxManage storagectl "$VM" --name "IDE Controller" --add "ide"

$ VBoxManage storageattach "$VM" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium $VDI

# ダウンロードしたseed.isoファイルを指定
$ VBoxManage storageattach "$VM" --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium seed.iso

# ssh接続用のネットワーク設定
$ VBoxManage modifyvm "$VM" --natpf1 "ssh,tcp,127.0.0.1,2222,,22" --memory 1024 --vram 8 --audio none --usb off

# VMを起動
$ VBoxManage startvm "$VM" --type headless
```

### 2.5 VMにログイン
下記コマンドで[Vagrant 公開鍵・秘密鍵](https://github.com/hashicorp/vagrant/tree/master/keys)の秘密鍵をダウンロード後、その鍵を指定してsshで接続する。

```shell=
# Vagrant insecure private keyのダウンロード
$ curl -sL https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant -o vagrant.pem

# SSHで接続する
$ ssh -p 2222 vagrant@localhost -i vagrant.pem
・
・
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes　←「yes」と入力
```
### 2.6 カーネルの更新

```shell=
# カーネルの更新
$ sudo yum -y update kernel
$ sudo reboot

# SSHで接続する
$ ssh -p 2222 vagrant@localhost -i vagrant.pem
```

### 2.7 VirtualBox Guest Additions のインストール
1. VirtualBoxから「表示」→「デバイス」→「光学ドライブ」→「仮想ドライブからディスクを除去」でISOイメージ（seed.iso）を取り外す。※「強制マウント解除」を選択

2. 「デバイス」→「Guest Additions CDイメージの挿入」を選択する。

3. 仮想マシンで以下のコマンドを実行し、VirtualBox Guest Additions をインストールする。

```shell=
$ sudo mount -r -t iso9660 /dev/cdrom /media
$ sudo /media/VBoxLinuxAdditions.run
$ sudo umount /media
$ sudo systemctl enable vboxadd.service
```

### 2.8 クリーンアップ
VMに接続後VirtualBox上で動いているVMをボックス化した時のサイズを小さくするために不要な物を削除後、シャットダウンする。

```shell
# 起動時に保存されたMACアドレスを削除
$ sudo rm -f /etc/udev/rules.d/70-persistent-net.rules

# yum のキャッシュを削除
$ sudo yum clean all
$ sudo rm -rf /var/cache/yum

# /var/log ディレクトリに出力されたのログを削除
$ sudo find /var/log -type f -exec cp -f /dev/null {} \;
# 仮想ハードディスクの領域を最適化
$ sudo dd if=/dev/zero of=/0 bs=4k
$ sudo rm -f /0

# コマンド履歴を残さないようにする
$ export HISTSIZE=0
# historyの履歴を削除
$ cat /dev/null > ~/.bash_history
$ exit

# 仮想マシンを停止
$ vagrant halt
```

### 2.9 Vagrant boxの作成と登録
VMをボックス化してVagrantに登録し、管理できるようにする。
vagrant2.2.6の場合、vagrat box add時にboxファイルのパスを絶対パスで指定しないとエラーになるみたいなので注意する。

```shell
# VirtualBoxで動いているVMを指定。デフォルトではpackage.boxという名前のファイルが作成される。
$ vagrant package --base "$VM"

# package.boxに指定した名前を付けて、Vagrantに登録
# package.boxは絶対パスで指定
$ vagrant box add --name "amzn2" /w/hogehoge/package.box
        ・
        ・
        ・
```

### 2.10 起動・ログイン・停止・破棄

```shell
# 仮想マシン用のフォルダを作成
$ mkdir amazonlinux2
$ cd amazonlinux2

# 登録したboxの名前を指定する。コマンド実行後、Vagrntfileが作成される。
$ vagrant init amzn2

# VMがVirtual Box上に作成され、起動する。
$ vagrant up

# VMにログインする。
$ vagrant ssh

# VMを停止する。
$ vagrant halt

# VMを破棄する。VirtualBox上から削除される。
$ vagrant destroy
```

## 3. （おまけ）vagrant実行時のエラー解決方法

エラー①
Git Bashでvagrantコマンドを実行した際に下記のサイトのようなエラーが発生しましたが、記事内容を参考にGit Bashの「Options」→「Text」でCharacter setを「UTF-8」→「SJIS」にして解決。

[VagrantでEncoding::UndefinedConversionErrorを食らった時の解決策](https://qiita.com/yukinissie/items/969db7110845f66e80ec)

エラー②
vagrant box addコマンド時に以下のエラーが発生しましたが、package.boxファイルのパスに日本語が含まれるのが原因らしいので、フォルダパスを変更後、Git Bashを新しいファイルパスで開いて再度コマンドを実行して解決。

```shell
C:/HashiCorp/Vagrant/embedded/mingw64/lib/ruby/2.6.0/uri/rfc3986_parser.rb:21:in `split': URI must be ascii only "file:///j:/・・・・/package.box" (URI::InvalidURIError)
```

## 4. 参考サイト
 [Amazon Linux 2 を仮想マシンとしてオンプレミスで実行する](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/amazon-linux-2-virtual-machine.html)
 [Amazon Linux 2 LTSの綺麗なVagrant boxを作ってみた（2.0.20180622.1）](https://qiita.com/ShibuyaBizman/items/db503feb6be555dc32ac)
 [Amazon Linux2のVagrant Boxを作成する](https://toripiyo.hatenablog.com/entry/2019/05/03/132545)
 [AmazonLinux2のVagrant boxを作成してみた](https://qiita.com/sonodar/items/d7d51d286c1c3a365127)
 [Amazon Linux 2 の Vagrant Base Box を作成する](https://qiita.com/aibax/items/7fd9a874cb7e88f95488)
 [Windows10 で Amazon Linux 2 を vagrant で動かすまで](https://qiita.com/tutida/items/22e02766150790bc90be)