WordpressをAWS(Elastic Beanstalk+RDS+S3+CloudFront)に移行


WordpressをさくらVPS1台からAWSにサーバ移行を行ったので、それに関する流れをメモしてみました
ところどころ詰まったので、2日くらいかけて作業していたと思います

### 使用したAWS環境

- Elastic Beanstalk
- RDS
- S3
- CloudFront

# Elastic Beanstalk立ち上げ
ここは他に分かりやすい記事がたくさんあるので、そちらを確認した方が良いかと思われます


## アプリケーション登録
サーバから画像ファイル(`wp-content/uploads`)を抜いたファイルを全てダウンロード

```
rsync -ahv --exclude='uploads/*' hoge@***.***.***.***:/var/www/html/アプリケーション名 ~/Documents
```

このファイルを指定して、Elastic Beanstalkを立ち上げます
(ユーザ情報や、固定ページなどそういった情報は保持されません。データベースの移行を行うと移行されます)

## Wordpressセットアップ
RDSを立ち上げる時に指定したユーザ名・パスワードを指定します
データベース名はデフォルトの`ebdb`です

# データベースの移行
MySQLのデータベースをRDSに移行します

## RDSのセキュリティグループの変更
EC2インスタンス→セキュリティグループ→対象のRDSを選択
インバウンドで許可するIPアドレスを登録できます
今回はデータを移行するので、移行元のサーバのIPアドレスを登録しました

- タイプ: MYSQL/Aurora
- プロトコル: TCP
- ポート範囲: 3306
- 送信元: サーバのIPアドレス(160.*.*.*/32)

IPアドレスですが`/32`を指定してユニキャストにする必要があります

## RDS設定の変更
RDSのインスタンス→インスタンスの操作→変更から
ネットワーク&セキュリティのパブリックアクセス可能を「はい」にします
また、メンテナンスのすぐに適用にチェックを入れることで即変更できます

インスタンスのステータスが変更中から利用可能に変わったらアクセス可能です
以下のコマンドでアクセスできます

```
mysql -h ***.ap-northeast-1.rds.amazonaws.com -u ユーザ名 -p -P 3306
```

## 移行
データベースをdumpしてから実行

```
mysqldump -u root -p データベース名 > dump.sql

mysql -h ***.ap-northeast-1.rds.amazonaws.com -u ユーザ名 -p -P 3306 ebdb < dump.sql
```

# 画像データの移行
画像データをS3に移行します
色々な方法があるかと思いますが、今回はAWS CLIを用いて同期する方法を選びました

## AWS CLIインストール
[AWS CLI のインストールと設定](http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html)を参考にインストールします
CentOSなので、次のような手順を踏みます

```
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py

sudo pip install awscli
```

これでコマンドライン上でS3の設定・アップロードなどができるようになります

## AWS CLI設定
`aws configure`で設定をします
これを行う前に、S3を扱う事ができるIAMユーザを準備しておくと便利です

```
aws configure
AWS Access Key ID [None]: アクセスキー
AWS Secret Access Key [None]: シークレットアクセスキー
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

## アップロード
以下のコマンドでアップロードします
配信の準備のため移行先は`/wp-content/uploads/`とします

```
aws s3 sync uploads/ s3://バケット名/wp-content/uploads/
```

# CloudFrontで画像配信
リクエストされたURLが`http://***/wp-content/uploads/*`の場合はS3に見に行ってもらうように設定します
こうする事でデータベースの画像リンクなどを書き換える必要がなくなります

## 設定
[AWS CloudFrontを使ってWordPressのメディアファイルだけS3に配置する](http://dev.classmethod.jp/cloud/aws-beanstalk-wordpress-2/)
こちらを参考にしました

### CloudFrontの設定(通常ファイル)
Create Distributionsを選択

<img src="https://qiita-image-store.s3.amazonaws.com/0/88553/09ee7a2f-0769-b771-105a-c07eceadac8c.png" width="640">

Webを選択して、項目を記入していきます
さきほど参考にあげた[サイトさん](http://dev.classmethod.jp/cloud/aws-beanstalk-wordpress-2/)が詳しく説明されているので、そちらを参考にされると良いと思います

<img src="https://qiita-image-store.s3.amazonaws.com/0/88553/337f2fdf-5d3b-374d-f7f9-fab82be1e8d8.png" width="640">

ちなみに、まだ本番のドメインを使わずにテストだけ…という場合は`Alternate Domain Names (CNAMEs)`はまだ記入しなくても問題ないです(記入しておいても問題ないです)

最初のこの登録は、
**リクエストがあったときにElastic Beanstalkで立ち上げたロードバランサに誘導する**
といった目的のものとなります

### Deployedまで待つ
CreateしてもDeployedになるまで15分かもうちょっとかかります
結構かかるので気長に待ちます

### CloudFrontの設定(画像ファイル)
DeployedされたらそのDistributionを選択します

<img src="https://qiita-image-store.s3.amazonaws.com/0/88553/2215d7c8-bd71-35eb-ea07-ea9f65dd4cde.png" width="640">

ずらっと並ぶタブから2つ設定します

- Origins
- Behaviors

OriginでS3を登録して、Behaviorでパスが`/wp-content/uploads/*`だったらS3に飛ばす旨を登録します
これも先程の参考サイトさんを見ていただくと分かりやすいかと思います

この登録で
**画像のリクエストがあったときに、CloudFrontに誘導する**
ことができました

## Wordpressプラグイン

- [Amazon Web Services](https://ja.wordpress.org/plugins/amazon-web-services/)
- [WP Offload S3 Lite](https://ja.wordpress.org/plugins/amazon-s3-and-cloudfront/)

これらを登録し、Access Keysにアクセスキーやシークレットキーを登録します
S3 and CloudFrontでは次のように設定します

<img src="https://qiita-image-store.s3.amazonaws.com/0/88553/6a611830-a7ea-2c6f-3147-57627b172bce.png" width="640">

テスト中はカスタムドメインのところにCloudFrontのドメインを登録すると良いかと思われます
本番のドメインを使用する際になったらそちらに変更してください

## 表示の確認
以上でCloudFrontの設定は完了です
CloudFrontのDistributionに表示されているDomain Nameにアクセスするとサイトが表示され、S3にある画像にもアクセスできるようになります

### 504 Timeout エラー
CloudFront経由で記事のページがいくらたっても表示されませんでした
また、カテゴリのページも時間がかかりました
以上の状況から、`get_categories`のある部分を消す事によって、記事のページが表示されるようになりました

CloudFrontではタイムアウトが30秒(10秒？)に設定されているらしく、処理に時間がかかりすぎると接続が切れてしまいます
Wordpressの処理速度をテストしていく必要がありそうです

# まとめ
実際何度か作業に詰まりましたが、見返してみると非常に簡単な作業であることが分かりました
インフラエンジニアではないので分からない事も多かったのですが、都度調べる事で追いつける程度ではあります