WordPressをCloudFront+ALBにて配信する

こんにちは。wevnal大城です。

前回([wpXクラウドで運用しているWordPressをAWS for KUSANAGIに移行した話](https://qiita.com/wevnaloshiro/private/55cbd42197f3dea4361c))、WordPressをwpXクラウドからAWSへ引っ越しました。
今度は高トラフィックに対応できるようにCloudFront経由でサイトを配信できるよう設定します。合わせてサイトをSSL化するためにApplication Load Balancer(以下、ALB)を利用します。
また、SSL証明書はAWS Certificate Manager（以下、ACM）を利用して取得します。

#目次
1.構成
2.Route53の設定
3.ACMによるSSL証明書の取得
4.ALBの設定
5.CloudFrontの設定

##構成
前回作ったEC2の通信の前段に高トラフィック対応としてのCloudFrontとサイトSSL化のALBを配置します。

AWSではCloudFront・ALBにてACMにて発行するSSL証明書を利用することができます。

CloudFrontにてhttpsのみを受け付けてEC2へhttpで通信させる場合、CloudFront側でキャッシュヒットしなければ、ユーザーからEC2へhttpでアクセスされることになります。EC2もhttpsのみを受け付けるように構成すれば良いのですが、SSL証明書を別途用意する必要がありコストと手間がかかります。そこで、ALBでACMのSSL証明書が使えることを利用して、CloudFrontとEC2の間にALBを配置することとし、外部ーCloudFront間、CloudFrontーALB間の両方でSSL証明書を設定してEC2までの通信をSSL化します。

画像の中の①はhttps、②はhttpで通信することにします。
<img width="100%" alt="スクリーンショット 2018-09-04 16.45.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/277566/024e3683-a7f4-9619-d4f9-406501a56a69.png">

##Route53の設定
ドメインはお名前.comにて取得していることとします。
Route53を利用すると、CloudFront、ALBと容易に連携できます。
まずRoute53の設定を行います。

HostedZoneを新規で作成し、お名前.com側で設定しているAレコードを設定します。
そうするとRoute53にてNSレコードが作成されます。
![スクリーンショット_2018-09-04_18_07_15.png](https://qiita-image-store.s3.amazonaws.com/0/277566/d725b07c-a017-bfa8-b82b-e6da1d880438.png)

そして、お名前.com側にて上記で作成されたNSレコードを設定します。
これで、対象ドメインがRoute53側のDNSを利用する設定が完了しました。

参考：https://qiita.com/ysKey2/items/0545e13ec05def42ad55

##ACMによるSSL証明書の取得
ACMの証明書の発行、および利用は無料です。さらに、証明書は自動更新されるためメリットがあります。
しかし、利用できるのはALB、CloudFront,API Gatewayと限られています。

今回はACMを利用してCloudFront、ALBにて設定するSSL証明書を取得します。

ACMでは東京リージョンでも証明書の作成が可能ですが、CloudFrontの証明書の場合はバージニア北部で作る必要があります。東京リージョンで作成した場合はCloudFrontには設定できません。今回の構成では外部ーCloudFront間はバージニア北部、CloudFrontーALB間では東京リージョンで作成します。

ACMはドメイン認証SSL証明書です。そのため、登録する際に認証メールを受け取る必要があります。
今回はメールを受け取るために[Amazon SES](https://aws.amazon.com/jp/ses/)を利用します。ドメイン認証のメール受け取りができない環境の場合でもSESを利用するとメールを確認することが可能です。下記のURLを参考に設定することで、S3に受信メールを格納することができました。

参考：https://dev.classmethod.jp/cloud/aws/acm-verifydomain-ses/

##ALBの設定
前述のACMにて取得したSSL証明書を設定します。
ここでつまづいたのが、ALBには複数のアベイラビリティゾーンを設定する必要があることです。
私の場合はパブリックなアベイラビリティゾーンが1つしかなく、あたらしくアベイラビリティゾーンを追加する必要がありました。

追加すると、ALBの設定が可能となります。
設定後、Route53のIPv4のAliasにALBのDNSを設定すると、ALB経由でhttpsにてサイトを公開することが可能となります。

##CloudFrontの設定
最後にCloudFrontの設定を行います。
問い合わせ系やGA計測もキャッシュされると問い合わせメールが送れない、GA計測されないなどの挙動がおかしくなることがあるので、気をつけて設定します。

以下のルールでキャッシュ設定を考えます。
・WP管理画面、WPログイン画面はキャッシュしない
・PHPはキャッシュしない
・上記以外はデフォルトTTLでキャッシュする

Behaviors
<img width="1213" alt="behaviors.png" src="https://qiita-image-store.s3.amazonaws.com/0/277566/fd28b6f5-066d-5948-3ea3-ca640d800f0e.png">

Default(*)
![default-1.png](https://qiita-image-store.s3.amazonaws.com/0/277566/a268c019-b28a-6a39-5f35-d3216198e140.png)
Whitelist Heardersに

```
CloudFront-Forwarded-Proto
Host
```
を設定します。
Origin側へプロトコルとアクセス先ホスト名を通知するために追加します。

![defaulet-2.png](https://qiita-image-store.s3.amazonaws.com/0/277566/0eb29095-2a44-a12a-495d-06d22a4cb9ee.png)
GAを利用しているため、Whitelist Cookiesに

```
wp-settings*
wordpress_logged_in*
```
を設定しました。

wp-admin,wp-login,*.php
![php-1.png](https://qiita-image-store.s3.amazonaws.com/0/277566/98c9f756-9028-0138-2b0f-b184ae9ab72a.png)
![php-2.png](https://qiita-image-store.s3.amazonaws.com/0/277566/aa5e6390-8b6e-cd97-cd99-151340bf937d.png)
Minimum TTL,Maximum TTL,Default TTLを全て0に設定することでキャッシュが効かないようになります。

これだけでは、一部のプラグインでキャッシュされてしまい挙動がおかしくなったところがありました。キャッシュにより挙動がおかしくなった処理に対しては、Behaviorsに上記のようにキャッシュしない設定を追加することで対応可能です。

これまでの設定の結果、CloudFrontにて８割程度キャッシュに成功しました。
上出来ではないでしょうか。
<img width="1017" alt="スクリーンショット 2018-10-03 1.14.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/277566/80006a89-5b25-59f4-9b8a-16c28d154248.png">

参考：
https://qiita.com/kunitaya/items/1a78cd2d4d2971394e0d
https://qiita.com/kunitaya/items/876a12cc803c5d495f43

以上で、無事にCloudFront+ALBの設定が完了しました。
これで急なアクセス集中が発生してもキャッシュされているページを表示することができる構成にすることができました。