VMWareの仮想環境をVM Import/ExportでEC2に移行する

稼働中のサービスをAWSに移行することがあったので、その時のメモです。

## 環境

- CentOS6.4

## 参考にさせていただいたサイト

http://edu.jtp.co.jp/column/89
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/CommandLineReference/set-up-ec2-cli-linux.html
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/CommandLineReference/ApiReference-cmd-ImportInstance.html
http://hacknote.jp/archives/13234/

## 手順

1. S3 Bucketを用意する。
2. EC2 API Toolsをインストールする。
3. OVFToolをインストールする。
4. OVFToolでディスクイメージを書き出す。
5. EC2 API ToolsでVM Import/Exportを実施してEC2に移行する。
6. 動作確認とAMI化をする。

## 1. S3 Bucketを用意する。

移行に際して、ローカル環境のイメージはS3にアップロードされてから変換される流れになります。従ってS3 Bucketを用意しましょう。

（作り方は割愛します。）

## 2. EC2 API Toolsをインストールする。

インポート自体はコマンドラインツールによって行いますので、インストールします。インストール方法は [公式ドキュメント](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/CommandLineReference/set-up-ec2-cli-linux.html#java_runtime_linux) に従って行えばよいです。

### 2-1. コマンドをダウンロードする。

```shell-session
wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip
```

### 2-2. ファイルを解凍する。

```shell-session
mkdir /usr/local/ec2
sudo unzip ec2-api-tools.zip -d /usr/local/ec2
```

### 2-3. 環境変数を用意する。

```shell-session
which java
#=> /usr/bin/java

file $(which java)
#=> /usr/bin/java: symbolic link to `/etc/alternatives/java'

file /etc/alternatives/java
#=> /etc/alternatives/java: symbolic link to `/usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java'

file /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java
#=> /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

export JAVA_HOME=/usr/lib/jvm/jre-1.6.0-openjdk.x86_64
export EC2_HOME=/usr/local/ec2/ec2-api-tools-1.7.5.1
```

下から3行分の `export` は `.bashrc` なりに書いておくと良いでしょう。
上の方の `which` や `file` コマンドではjavaの置き場所を探しています。これも公式ドキュメントに書かれてある手順の通りですので、そちらも見てください。結果的に出てきている `$JAVA_HOME` はあくまでも僕の環境での値です。

### 2-4. PATHを通す。

```shell-session
export PATH=$PATH:$EC2_HOME/bin
```

こちらも `.bashrc` に書いておくと良いです。

### 2-5. 動作を確認する。

```shell-session
ec2-describe-regions -O FOOACCESSKEYID -W foosecretaccesskey
#=> REGION      ap-south-1      ec2.ap-south-1.amazonaws.com
#=> REGION      eu-west-1       ec2.eu-west-1.amazonaws.com
#=> REGION      ap-southeast-1  ec2.ap-southeast-1.amazonaws.com
#=> REGION      ap-southeast-2  ec2.ap-southeast-2.amazonaws.com
#=> REGION      eu-central-1    ec2.eu-central-1.amazonaws.com
#=> REGION      ap-northeast-2  ec2.ap-northeast-2.amazonaws.com
#=> REGION      ap-northeast-1  ec2.ap-northeast-1.amazonaws.com
#=> REGION      us-east-1       ec2.us-east-1.amazonaws.com
#=> REGION      sa-east-1       ec2.sa-east-1.amazonaws.com
#=> REGION      us-west-1       ec2.us-west-1.amazonaws.com
#=> REGION      us-west-2       ec2.us-west-2.amazonaws.com
```

上記はリージョンを一覧表示するコマンドです。これが動けばインストール完了です。 `-O` オプションと `-W` オプションにはそれぞれ `access_key_id` と `secret_access_key` を入れてください。環境変数としてセットしておくことも可能です。今回はこの環境を後で壊すので直接コマンドに書いています。

これでEC2 API Toolsはインストール完了です。

#### Tips: `ec2-describe-regions` に失敗する場合は？

僕の環境ではこのコマンドは最初は `401` エラーが出て失敗しました。他の環境ではいつも普通に使えるのに何故・・・。調べた所、 [OSの時刻がズレているとエラーが出る](http://hacknote.jp/archives/13234/) とのこと。 `ntpdate` コマンドで時刻を直しましょう。

```shell-session
date
#=> 2016年  8月  8日 月曜日 12:20:12 JST

ntpdate -b ntp.nict.jp
#=> 8 Aug 12:07:36 ntpdate[31721]: step time server 133.243.238.244 offset -765.667802 sec

date
#=> 2016年  8月  8日 月曜日 12:07:38 JST # ズレ杉ぃ！
```

## 3. OVFToolをインストールする。

VMWareのイメージをOVF形式で書き出すには、VMWare謹製の [OVFTool](https://my.vmware.com/jp/web/vmware/details?productId=352&downloadGroup=OVFTOOL350) が必要になります。インストールしましょう。

ダウンロードするにはMy VMWareへのアカウント登録が必要ですので、先に登録してください。

対応OSにはWindowsとMacとLinuxがあります。今回はLinuxを使います。ダウンロードした `.bundle` ファイルを実行すればインストールされます。実行権限を与えるのを忘れないで下さい。

```shell-session
chmod gu+x VMware-ovftool-3.5.0-1274719-lin.x86_64.bundle

./VMware-ovftool-3.5.0-1274719-lin.x86_64.bundle
```

## 4. OVFToolでマシンイメージを書き出す。

マシンイメージを書き出します。マシンイメージ自体は `.vmx` というファイルを使用しますので、見つけてください。

```shell-session
ovftool /var/vmware/images/foo/foo.vmx /usr/local/etc/foo/foo.ovf
```

上記コマンドで書き出されます。ちょっと時間がかかります。（サイズによる。）保存場所は、僕の場合は `/usr/local/etc/` にしましたがどこでも良いでしょう。どうせ後で消すし。

```shell-session
ls /usr/local/etc/foo

foo-disk1.vmdk  foo.mf  foo.ovf
```

上記のようにディスクイメージが作成されます。この後でインポートに使用するのは `.vmdk` です。

## 5. EC2 API ToolsでVM Import/Exportを実施してEC2に移行する。

全ての準備が整いました。ここまで来たらインポートするコマンドを実行すればほぼ完了です。コマンドのオプションについては [公式ドキュメント](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/CommandLineReference/ApiReference-cmd-ImportInstance.html) を参照してください。

```shell-session
ec2-import-instance \
  foo-disk1.vmdk \            # ディスクイメージ
    -f VMDK \                 # イメージのフォーマット
    -a x86_64 \               # アーキテクチャ
    -p Linux \                # プラットフォーム (Windows|Linux)
    -t t2.micro \             # インスタンスタイプ
    -s 30 \                   # インスタンスボリューム
    -g FooProdWeb \           # セキュリティグループ
    -z ap-northeast-1c \      # Availability Zone
    --subnet subnet-foo \     # サブネット
    -b s3-foo \               # 中継するS3 Bucket
    -o FOOACCESSKEYID \       # access key id
    -w foosecretaccesskey \   # secret access key
    --region ap-northeast-1 \ # リージョン
    - O FOOACCESSKEYID \      # access key id
    - W foosecretaccesskey    # secret access key
```
アクセスキーの指定が2回出てきますが（ `-o` と `-w` 、 `-O` と `-W` ）インポートのための認証と、S3中継時の認証で2つ必要とのことです。

#### Tips: イメージ変換中の状況確認をするには？

インポートはまずS3へのディスクイメージのアップロードから始まります。10MBずつに分割されてアップロードされていくのがS3のGUIコンソールからでも確認できるでしょう。

<img width="581" alt="スクリーンショット 2016-08-08 15.57.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/31401/2f917dca-1246-7c8b-b2d8-26b27521fa09.png">

アップロードが完了するとインスタンス立ち上げの前にディスクイメージの変換処理に入ります。この進捗状況は下記のコマンドで確認するということができます。

```shell-session
ec2-describe-regions -O FOOACCESSKEYID -W foosecretkeyid

TaskType	IMPORTINSTANCE	TaskId	import-i-foo	ExpirationTime	2016-08-15T04:43:26Z	Status	completed	InstanceID	i-foo
DISKIMAGE	DiskImageFormat	VMDK	DiskImageSize	6331476480	VolumeId	vol-foo	VolumeSize	30	AvailabilityZone	ap-northeast-1c	ApproximateBytesConverted	6331466240	Status	completed
```

## 6. 動作確認とAMI化をする。

イメージの変換が終わると、stop状態のEC2インスタンスとして用意されます。

<img width="773" alt="スクリーンショット 2016-08-08 16.01.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/31401/25aa93d6-fa69-5ec3-57d0-18033e2cd3f0.png">

これを起動して動作を確認した後に、AMIを保存すればいつでも使えるようになりますね。

出来上がったインスタンスにSSHログインする際は、（当然ですが）仮想マシンの中での設定がそのまま反映されています。（僕は何故か母艦の設定でログインしようとして少し焦りました笑）