AWSのClassic環境をVPCへと移行する

# Classicのコンプレックス
最近AWSを使い始めた人には意味が解らないと思いますが、
AWSにはClassicというVPCの中に入っていない構成（クラスタ）があります。
EC2やELCやRDSなどです。
自分が使っている環境はClassicで動いていてこれが結構前からコンプレックスでした（なんとなく）

新世代のインスタンスが使えなかったり、サービス自体が対応してなかったりで色々と不便が多いです。

とはいえ安易にサービスをstopしてメンテナンスタイムを取る事が出来ないのも実情です。
そこで少しでもダウンタイムを短く移行する事を考え実践した事を記述します。
（なのでしっかりとメンテタイムを取って移行する時間が取れる方にはあまり役に立たない記事です）

# 読むと参考になるかもしれない人
* AWSのClassic環境からVPCに移行したいと思ってる方
* 何かしらの理由でRDSでオレオレなreplicationを貼りたいと思ってる方

# ここでは記述しない事
* VPCのネットワーク設計について

# 今回の移行対象
* EC2(ElasticBeanstalkを利用）
* ElasticCache
* RDS


# ElasticCacheの移行
使い方によると思いますが、
基本的にElasticCacheに入れてるデータは揮発性(Redisは永続性とかいう突っ込みは無しで）なので
2重に書き込んでおいて、古い方がexpireして、新しい方にどんどん溜まってきたら古い方を切り離す
というアプローチができるはず。
ではどうやってVPCのリソースへアクセスするのか？

## ClassicLinkの光

ClassicLinkという機能を使うとClassicのEC2から一つのVPC内部へのリソースへとアクセス出来ます。
http://aws.typepad.com/aws_japan/2015/01/classiclink.html
（おそらく内部的にはサブネットをくっつけてるっぽい）
これをアプリケーションサーバに設定してClassicのEC2からVPC内のELCへアクセスします。

## まずはこんな感じになっています
![aws-move1.001.png](https://qiita-image-store.s3.amazonaws.com/0/27180/a9c0b305-c08d-75c8-a282-c1a7740cdcfc.png)

## ClassiLinkで繋ぐ
![aws-move.001.png](https://qiita-image-store.s3.amazonaws.com/0/27180/97aef513-2f94-eb2d-3e1a-2cf2204073af.png)

## 新しいCacheが温まったらClassic側はさようなら
![aws-move.002.png](https://qiita-image-store.s3.amazonaws.com/0/27180/228172c4-90bd-06e4-557c-ff25af14bef9.png)

## 

# RDSとEC2(ElasticBeanstalk)の移行

**と　に　か　く　辛　い　の　は　R D S だ**
**と　に　か　く　辛　い　の　は　R D S だ**
**と　に　か　く　辛　い　の　は　R D S だ**


200G近いRDSインスタンスだったためsnapshot作成してリストアしようとすると、
３時間以上かかる見積もりだった。
他の作業を含めるとどう考えても深夜だけでは終わらない。

そこでclassicにあるmasterからVPCへのreplicationが貼れないか模索してみたところ、
幾つか参考になる文章を見つけた。
(replicationさえ貼れれば最小の時間でmasterへ昇格出来る）

# ざっくりとした設計
http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/MySQL.Procedural.Importing.External.Repl.html
# ストアドプロシージャのリファレンス
http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.MySQL.SQLRef.html

どうもオンプレのMySQLからRDSへの移行のためのツールが用意されてるみたいで、
replication系のコマンドを直接叩く事は出来ないけどストアドプロシージャでの用意があるみたいです。

そこでいろいろ試してみて上手く行ったのでここに残しておきます。
（自己責任必須でございます）


## 大まかな流れ
### 準備
* ClassicのRDSからオレオレなreplicationでVPC側に新しいmasterを作成する
    * [オレオレreplicaを作る方法](#oreore)


![aws-move.004.png](https://qiita-image-store.s3.amazonaws.com/0/27180/6a0da734-ad96-5a2e-4ef5-e00e29516772.png)

### メンテナンス日
#### 必要ならVPC側でサービスに使うreplicaを作成する（オレオレでなく通常のコンソール or cliで）多段でreplicationしている状態
![aws-move.006.png](https://qiita-image-store.s3.amazonaws.com/0/27180/a5d8ad32-0a45-31e5-59f6-0c75008ef2f2.png)

#### VPC側にアプリケーションサーバのセットを組む
![aws-move.007.png](https://qiita-image-store.s3.amazonaws.com/0/27180/2abf7369-ae6e-334d-d7a5-4dc5e0ee35f2.png)

#### classicのアプリケーションサーバからのreadをvpc側へ向ける(ClassicLink)
![aws-move.001.png](https://qiita-image-store.s3.amazonaws.com/0/27180/c1ab33d8-576f-0248-a449-e4bd0dec9f30.png)

#### ダウンタイム開始(メンテナンスモード等）

##### vpc側からclassicのmasterへ貼っているreplicationをstopする
![aws-move.001.png](https://qiita-image-store.s3.amazonaws.com/0/27180/3ce16df8-e027-1b94-0102-ccd35e1fd116.png)

##### Route53やELB等使用しているサービスリクエストの向き先をVPC側の環境に変更する
![aws-move.001.png](https://qiita-image-store.s3.amazonaws.com/0/27180/df086d7e-983d-b1cf-c04b-febcc0db62eb.png)

#### ダウンタイム終了
* 数分(上手く行けば数秒)のダウンタイム確保で移行出来る


## <a name="oreore">一番のポイントであるオレオレなreplicaを作成してmaster昇格候補とする方法</a>
* オレオレreplicationでVPC側にmasterを作成する方法（vpc側で次期master昇格)
* 稼働中のRDSからサービスに使用しないreplicaを作成する
* 作成したreplicaの自動バックアップを有効にする
* Classic側のmasterと作成したreplicaのbinlog保存期間を適当な時間にセットする（保存するようにする）
* 以降のコマンドはRDSのadminなユーザで行ってください
    * ex:6hにセットする
        * ```call mysql.rds_set_configuration('binlog retention hours', 6);```
        * call mysql.rds_show_configuration; (確認)
* 作成したreplicaのreplicationを止める
    * ```call mysql.rds_stop_replication;```
    * stopしたreplicaからreplicationの情報を取得する
    * ```show slave status\G;```
      * ```Read_Master_Log_Pos: nnn Master_Log_File: mysql-bin-changelog.nnn``` この2つを控える
* replicationを止めたreplicaからsnapshotを取得する
    * snapshotが出来上がったらこのreplicaは不要になるのでterminateしてもok(実際は他作業が終わるまで取っておいてもいい気がする）
* 作成したsnapshotからvpc側に新規masterを作成する
* vpc側からclassicへbinarylogを取得出来るようにセキュリティグループを設定する
    * port3306が通信できればok
* VPC側のmasterからclassic側のmasterをreplicationのmasterとして指定する
  * ```CALL mysql.rds_set_external_master(‘masterのホスト名', 3306, ‘replicationユーザ名', 'パスワード', ‘Master_LogFileで取得したバイナリログファイル', Read_Master_Log_Posで取得したposition, 0);```
  * 最後の0はsslを使うかどうかのオプション。
* vpc側のmasterでreplication開始
    * ```CALL mysql.rds_start_replication;```
    * ```show slave status```のSeconds_Behind_Masterが追いついたらreplication完了

# まとめ
* 実際はHAProxyを使ったより短い移行プロセス&ロールバックの確保を行ったが本題ではない&複雑な話になるので割愛しました
* ちなみにRDSのsnapshot機能は素晴らしいです。リストアにやたら時間がかかるのはアーキテクチャの問題。
* それでも移行用のツールを残しておいてくれたお陰でなんとかVPCへ移行出来た。
* メンテ完了したらすぐ打ち上げに行きたいところですが、一日くらいは様子をみておきましょう。