Route53+CloudFront+S3の連携

# 背景
下記のような点を実現したかった。

* 本番サーバが落ちる等して障害が発生した際でもメンテ画面を表示できる
    * Route53にて障害時の振り分け
* メンテ画面を検索エンジンにインデックスさせない
    * CloudFrontで設定
* コストは安く
    * EC2じゃなくS3で
* 静的ファイルをS3に配置

諸々検討した結果、下記のような環境を構築することにした。
その中の未マスク部分がとりあえず出来たので、
備忘録がてら残しておく。

[![Screenshot from Gyazo](https://gyazo.com/ee89a5391833196f797123935d4882e6/raw)](https://gyazo.com/ee89a5391833196f797123935d4882e6)

# 実現方法
## S3
### 障害時用
* 専用バケットを作成
* プロパティ
    * `Static website hosting`
        * インデックスドキュメントに `maintenance.html` を指定し、配備する
    * アクセス権限
        * パブリック
        * CORSの設定
            * `<AllowedHeader>*</AllowedHeader>`
            * `<AllowedOrigin>*</AllowedOrigin>`
            * ![](https://gyazo.com/7322f868beebfd91372a3b8b95ed516f.png)

###  正常時用
* 専用バケットを作成
* プロパティ
    * `Static website hosting`
    * アクセス権限
        * パブリック

### 注意点
* ホスティング用のエンドポイントと通常のエンドポイントがあり、動きがちょっと変わってくるので使用する方を注意する

## Cloud Front
### 障害時用
* 設定
    * Origin Domain Name：障害用s3バケットの`Static website hosting`のエンドポイント
        * [![Screenshot from Gyazo](https://gyazo.com/7641f327528a443c219965f966225b0d/raw)](https://gyazo.com/7641f327528a443c219965f966225b0d)
    * Alternate Domain Names：Route53に登録される、対象domain
    * Default Root Object：index.html
        * 存在しないURLを指定する事で404エラーを発生させ、ErrorPagesで設定したエラー時のレスポンスページを表示
* Error Pages
    * HTTP Error Code：404
    * Response Page Path：`/maintenance.html`
    * HTTP Response Code：503
        * 検索エンジンがインデックスしないよ
            * [refs：サイトメンテナンス時には、HTTP 503エラーを使う](https://www.suzukikenichi.com/blog/using-503-error-at-site-maintenance/)

### 静的ファイル用
* 設定
    * Origin Domain Name：静的ファイル用s3バケットの`Static website hosting`のエンドポイント
    * Alternate Domain Names：Route53に登録される、対象domain
* Behaviors
    * Allowed HTTP Methods：GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
    * Cache Based on Selected Request Headers：All
    * Forward Cookies：All
    * Query String Forwarding and Caching：Forward all, cache based on all

### 注意点
* Request内のキャッシュやCookie等諸情報をwebサーバに送るかどうかの指定をBehaviorsでしている。その辺をよく使っているアプリは設定次第で動きが変わる可能性があるので注意する。
    * デフォルトだとRequest情報をほぼほぼwebサーバに送っていない
* Route53と連携する場合、Route53からCloudFrontへの指定と、CloudFrontからRoute53への指定の両方があり、両方指定しないとうまく動かないので注意
* エラーページが検索エンジンにインデックスされたらかっこ悪い
* キャッシュによってコンテンツが反映されない事がよくあるのできちんと確認する

## Route53
### Hosted zones
#### 障害時用(障害発生時)
* Name：正常時用と同一
* Type：A
* Alias：Yes
    * Alias Target：障害時用のCloudFrontのエンドポイント
* Routing Policy：Failover
    * Failover Record Type：Secondary

#### 障害時用(正常時)
* Name：障害時用と同一
* Type：A
* Alias：No
    * TTL：60（すぐ切替えられるよう短め）
* Routing Policy：Failover
    * Failover Record Type：Primary
* Associate with Health Check：Yes
    * Health Check to Associate：対応するHealth Check

#### 静的ファイル用
* Name：任意
* Type：CNAME
* Alias：No（Yesでも良いかも？）
    * Value（Alias Target）：対応するCloudFrontのエンドポイント

### Health checks
* Name：任意
* Protocol：対応するもの
* IP address：対応するもの
* Host name：対応するもの
* Port：対応するもの
* Path：対応するもの

# TODO
* cloudfront使う場合はs3のホスティング設定はいらないとかなんとか。要調査。
    * [Ref: S3+ACM+CloudFront+Route53で独自ドメインでhttpsホスティングする](https://qiita.com/haracane/items/287f2a35c03e33683875#s3%E3%81%A7%E3%83%9B%E3%82%B9%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88)
* コンテンツの即時反映がまだできていない時があるっぽい

# Refs
* [CloudFront最近の事例と間違った使い方](https://www.slideshare.net/hz_ouchi/cloud-front-30133315)
* [Cloudfrontで、「error the request could not be satisfied. generated by cloudfront (cloudfront)　」の対応](http://blog.ybbo.net/2015/04/11/how-to-fix-error-of-error-the-request-could-not-be-satisfied-generated-by-cloudfront-cloudfront-on-aws-cloud-front/)
* [Route 53のHealth checkでフェイルオーバーを設定する](https://qiita.com/skouno25/items/a1c2f82ced79381a361b)
* [CloudFront+S3+Route53でSorry Pageを表示してみる](https://qiita.com/A_K_Turry/items/fe94a3d2e894d7807a40)
* [S3+CloudFront+Route53で503なSorryページを安価に実現する](http://hiroohi.hatenablog.com/entry/2016/02/01/123959)
* [AWS S3 + CloudFront のCORS設定手順](http://blog.toshimaru.net/s3-cloudfront-cors-setting/)
* [代替ドメイン名 (CNAME) を使用する](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html)
* [CloudFrontで独自ドメインSSL設定](https://qiita.com/n0bisuke/items/a2a7d5efdc1311dc479a)


# 所感
AWS上の設定項目がバージョンアップしてるのか、記事にある設定と現在のAWSの設定とで一致しない所がたまにあり、
その際の適応が難しかった。
また、設定方法だけ書かれていたりほとんど着目されていない設定項目がどういう動きをするのか不明な所も多い。
AWSというかネットワーク周りの知識が足りてないなーと実感。
まぁ今回の調査でネットワーク周りのAWSの実現はなんとか作れるようになったかな。
あとはアプリ周りも近々やらなー。
Lambda使ってサーバレスなアプリとかも追々。。。