WordPressサイトをCloudFrontで配信する

#**概要**
##CloudFrontとは
![wp-cf.png](https://qiita-image-store.s3.amazonaws.com/0/80392/e9f4c7b4-e5ec-4ac5-8402-4706b14ab6fb.png)
CloudFrontはAWSのCDN(Contents Delivery Network)サービスで、Webサイトの前段に入れるだけでサイトアクセスが爆速になります。爆速になる理由は主に下記2点。

* 初回リクエストはCloudFrontがオリジンにコンテンツを取りに行きますが、2回目以降は超高速でCloudFrontのキャッシュから返答します。ただし、TTL(有効期間)を過ぎたキャッシュは削除されます
* ユーザーがアクセスするCloudFrontのエッジロケーションは全世界に54ヶ所(2016年1月現在)あり、ユーザーはネットワーク的に最も近いエッジロケーションに誘導されます。それぞれのエッジロケーションは、超広帯域なネットワークと超大容量なキャッシュ処理機構に支えられており、ユーザーがサイジングに悩む必要はありません

メディア暴露によるスパイク、いわゆるxx砲は、従来であれば予告されていたとしてもその対処は非常に大変だったわけですが、CloudFrontを使えば突然xxロケットランチャーが来たとしてもへっちゃらです！

＜公式ドキュメント＞
http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Introduction.html
＜参考資料＞
http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-2016-amazon-cloudfront

##何ができるのか
* WordPressサイトをCloudFrontで配信します
* WordPressサーバ(オリジン)はCloudFrontからのリクエストを処理するだけなので、サーバスペックは最低限でOKです
* WordPressサーバが落ちたとしても、エッジロケーションにキャッシュがある限り配信を継続できます(キャッシュ保持時間はTTL設定に依存)
* メールフォームなどのPOSTメソッドや検索クエリなどのGETにメソッドもOKです(全てオリジンで処理されます)

##前提条件
* AWSアカウントをもっていること
* DNSで名前解決できるWordPressサイトが立ち上がっていること。オリジンは必ずしもAWS上になくても構いませんが、本記事は下記手順で構築した環境が前提となっています<BR>
http://qiita.com/Ichiro_Tsuji/items/88f9009f80f3439ad9fa
* レコードを編集可能な独自ドメインを保有していること<BR>
※ もっていない場合は無料で取ってしまおう！<BR>
http://qiita.com/Ichiro_Tsuji/items/8471fe0b3d4d17cde146<BR>
* 手順中に登場するFQDN(サイトのURL)は下記の通りです。ご自分の環境に合わせて読み替えて下さい

```
Wordpressサイト -> wp.jaws-ug.tk
CloudFront経由 -> wp-cf.jaws-ug.tk
```

* 独自ドメインをもっていない場合は下記の通り読み替えて下さい

```
Wordpressサイト -> WordPressサーバのPublic DNS
CloudFront経由 -> CloudFrontのDomain Name
```

##料金
https://aws.amazon.com/jp/cloudfront/pricing/
CloudFrontのオンデマンド料金は、EC2からインターネットへの転送料金とほとんど同額です。
他にオリジンからの転送量やHTTPリクエストに対する課金がありますが、トータルで見ればEC2単体の時とさほど変わらないはずです。

#**プラグインの停止**
* WordPressの管理画面にログインする
* [プラグイン]をクリックする
* Nginx Cache Controllerが有効化されている場合は[停止]をクリックする
![プラグイン ‹ カレーは飲み物です — WordPress 2016-05-19 11-54-56.png](https://qiita-image-store.s3.amazonaws.com/0/80392/3ec5df29-0783-f373-92b8-34d7208b4dfd.png)

#**CloudFrontディストリビューションを作成する**
今回は、POST／GETメソッドは有効(ともにオリジンにスルー)とし、TTLはCloudFront側で一律に制御する設定とします。なお、TTLはコンテンツの`Cache-Control`や`Expires`ヘッダで個別に制御することも可能です。
[TTLについての詳細説明](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Expiration.html)

* AWSにサインインする
* CloudFrontコンソールを開く<BR>
![AWS Management Console 2017-06-24 16-13-54.png](https://qiita-image-store.s3.amazonaws.com/0/80392/eca6a581-703c-02ea-8c47-9e2ac748c889.png)
<BR><BR>
* [Create Distribution]をクリックする<BR>
![スクリーンショット 2016-02-07 21.14.50.png](https://qiita-image-store.s3.amazonaws.com/0/80392/b96226c2-ed14-7254-b464-fabfab89017f.png)
<BR><BR>
* Webの[Get Started]をクリックする<BR>
![スクリーンショット 2016-02-07 21.16.12.png](https://qiita-image-store.s3.amazonaws.com/0/80392/c8610270-7cb8-158d-f7c3-450e2b7bc6f2.png)
<BR><BR>
* Origin Domain NameにWordPressサイトのDNS名を入力してTabキーを押す
* Origin IDが自動的に生成されたことを確認する
* Allowed HTTP Methodsで[GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE]を選択する
* Object Cachingで[Customize]を選択し、希望のTTLを秒単位で入力する
* Forward Cookiesで[All]を選択する
* Query String Forwarding and Cachingで[Forward all, cache based on all]を選択する
* Alternate Domain Names(CNAMEs)にCloudFront経由でアクセスする場合のDNS名を入力する
* 2019年4月以降、代替ドメイン(CNAMEs)を設定する場合は、そのドメインの正当な所有者であることを証明することを目的に証明書の設定が必須化された。[証明書はACMで簡単にを生成することができる](https://qiita.com/ritya/items/989b1dbe706d6ae840e7)
* [Create Distribution]をクリックする<BR>
![screencapture-console-aws-amazon-cloudfront-home-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80392/11d728fb-bd90-3e64-c78d-4baa9a07cf10.png)
<BR><BR>
* Distributionの作成完了までに15分程度かかる<BR>
※ 待っている間に[DNSの登録](http://qiita.com/Ichiro_Tsuji/items/38592e737257cb45ca13#%E7%8B%AC%E8%87%AA%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%A7%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B)や[wp-adminをキャッシュさせない](http://qiita.com/Ichiro_Tsuji/items/38592e737257cb45ca13#wp-admin%E3%82%92%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%81%95%E3%81%9B%E3%81%AA%E3%81%84)を先にやっておくとよい
* IDをクリックする
![スクリーンショット 2016-02-07 21.21.15.png](https://qiita-image-store.s3.amazonaws.com/0/80392/4209d024-090d-af05-b916-6c0b8d4402d2.png)
<BR><BR>
* Domain Nameを確認する。これがCloudFront DistributionのEndpointとなるので、DNSにCNAMEレコードを登録(Route 53の場合は、AレコードAliasも可)することで独自ドメインでアクセスできるようになる(手順は次項で説明)
![スクリーンショット 2016-02-07 21.34.23.png](https://qiita-image-store.s3.amazonaws.com/0/80392/51e0a070-433e-6bc6-5a40-790e0baf2f78.png)
<BR><BR>
* Distributionの作成が完了すると[Deployed]に変わる
![スクリーンショット 2016-02-07 21.51.11.png](https://qiita-image-store.s3.amazonaws.com/0/80392/6343df21-0fe9-f1fb-7e27-e8411827f5cf.png)

#**独自ドメインでアクセスできるようにする**
##独自ドメインをRoute 53でホストしている場合
Alternate Domain Names(CNAMEs)に入力したFQDNでAレコードAliasを登録する
http://qiita.com/Ichiro_Tsuji/items/8471fe0b3d4d17cde146#aレコードaliasの登録
##独自ドメインをRoute 53 以外のDNSでホストしている場合
Alternate Domain Names(CNAMEs)に入力したFQDNでDNSにCNAMEレコードを作成し、CloudFrontのEndpoint(Domain Name)を登録する
##CloudFront経由でアクセスしてみる
CloudFrontのデプロイ完了後にDNSに登録したURL(独自ドメインをもっていない場合は、CloudFrontのDomain Name)でアクセスするとトップページが表示されるはずです。ただしこのままでは、ページ中のリンクなどがオリジンを向いてしまうので、WordPressの設定を変更します。
![スクリーンショット 2016-02-07 22.01.08.png](https://qiita-image-store.s3.amazonaws.com/0/80392/0d377b82-24dc-524e-5e6c-c064a10c43f8.png)

#**WordPressの設定を変更する**
* WordPressの管理画面にログインする
* [設定]をクリックする
* WordPress アドレス (URL)とサイトアドレス (URL)を、先ほどDNSに登録したCloudFrontのURLに変更する。独自ドメインをもっていない場合は、代わりにCloudFrontのDomain Nameを入力する<BR>
**※ ここの設定を誤るとWordPress管理画面にアクセスできなくなるので慎重に！！**設定を誤って管理画面にアクセスできなくなった場合は次項参照
* [変更を保存する]をクリックする
![スクリーンショット 2016-02-07 22.04.16.png](https://qiita-image-store.s3.amazonaws.com/0/80392/084d4e9c-1f0b-562b-a812-e76c4f5b2579.png)
<BR><BR>
* ログイン画面(CloudFrontのURL)に戻るので、ログインできることを確認する

##もし、管理画面にアクセスできなくなったら・・・
本来であればDBのレコードを直接修正して復旧する必要がありますが、暫定的にwp-config.phpを修正することで管理画面にアクセスできるようになります。

* WordPressサーバにSSHでアクセスし、下記コマンドを実行する<BR>
※ `http://wp-cf.jaws-ug.tk`は、CloudFrontのURL<BR>
※ `i-xxxxxxxx`は、AMIMOTO AMIインストール時に指定したインスタンスID。`i-`まで入力してTabキーで補完してもよい

```
$ cd /var/www/vhosts/i-xxxxxxxx
$ sudo cp wp-config.php wp-config.php.org
$ sudo vim wp-config.php
```

```php:wp-config.php
/*53行目あたり、//define('WP_DEBUG_DISPLAY', false);の後に追記する*/

define('WP_HOME','http://wp-cf.jaws-ug.tk');
define('WP_SITEURL','http://wp-cf.jaws-ug.tk');
```

##ログイン時のCookieエラー
ブラウザの種類によってはログイン時に下記エラーが表示されることがあります(Chromeで確認)。その場合はオリジン(WordPressサイト)のログインURLでログインしてみましょう。ログインに成功すればCloudFrontのURLに飛ばされるはずです。
それでもダメな場合は、[**wp-adminをキャッシュさせない**](http://qiita.com/Ichiro_Tsuji/items/38592e737257cb45ca13#wp-adminをキャッシュさせない)を試してみてください。
![スクリーンショット 2016-02-08 21.52.40.png](https://qiita-image-store.s3.amazonaws.com/0/80392/e2b1c178-33df-0238-f2f6-5f5443cb4c6b.png)

<!--
##「WordPress アドレス (URL)」が変更できない場合は
![スクリーンショット 2016-02-08 21.54.33.png](https://qiita-image-store.s3.amazonaws.com/0/80392/a67fa867-5885-6615-5afa-8de67262e3b6.png)
`wp-config.php`で「WordPress アドレス (URL)」や「サイトアドレス (URL)」に関係する部分をカスタマイズしている場合、上図のように当該箇所がグレーアウトします。オリジナルが残っている場合、WordPressサーバにSSH接続し、下記コマンドを実行することで初期状態に戻せます。(オリジナル=`wp-config.php.org`)
初期状態に戻したら、設定画面をリロードして下さい。
※ `i-xxxxxxxx`は、AMIMOTO AMIインストール時に指定したインスタンスID。`i-`まで入力してTabキーで補完してもよい

```
$ cd /var/www/vhosts/i-xxxxxxxx
$ sudo mv wp-config.php wp-config.php.custom  #現在のファイルをリネーム
$ sudo cp wp-config.php.org wp-config.php
```
-->

#**POSTできるか確認してみよう**
検索やコメント記入が機能するか確認してみましょう。
コメントは自動承認に設定している場合でも、最大でTTLの分だけ遅れて反映されます。

#**[WordPressサーバを停止](http://qiita.com/Ichiro_Tsuji/items/c6a52ec0ee95ead42f68#%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E5%81%9C%E6%AD%A2%E5%86%8D%E8%B5%B7%E5%8B%95%E6%99%82ip%E3%81%8C%E5%A4%89%E3%82%8F%E3%82%8B)してみよう**
CloudFrontにキャッシュが存在するページであればサーバを停止しても表示されるはずです。当然ながらPOSTは処理できませんし、TTLを過ぎたキャッシュは削除されてしまいます。また、CloudFrontに切り替える前に投稿された画像はキャッシュされずオリジンを参照します。
可用性と利便性を天秤にかけてTTLの値を決めて下さい。
※ EC2でElasticIPをアサインしていない場合、サーバ停止 -> 起動でグローバルIPが変わりますので注意して下さい。IPが変わってしまった場合は、オリジン向きののDNSレコードを修正する必要があります

#**wp-adminをキャッシュさせない**
wp-admin(設定画面)はキャッシュされると正常に動作しない場合があるのでキャッシュ対象外にします。キャッシュ対象外の設定を行うには、下記画面で[Create Behavior]をクリックしてBehaviorを追加し、**`/wp-admin/*`**のTTLを0に設定します。その他の設定値は、先ほどディストリビューションを作成した時と同じでOKです。
併せて動的コンテンツである**`*.php`**もキャッシュ対象外としておきましょう。
![AWS CloudFront Management Console 2016-07-17 21-24-12.png](https://qiita-image-store.s3.amazonaws.com/0/80392/96f46c34-2ca4-1ead-7c9f-9c257874063a.png)
![AWS CloudFront Management Console 2016-11-15 11-37-35.png](https://qiita-image-store.s3.amazonaws.com/0/80392/e0d85c3d-e88f-0c73-ab94-4f4a800b10d6.png)