[CloudFront, S3, ALB] “独自ドメインを使用した静的ウェブサイト”の拡張

AWSを使った静的サイトの制作において、以下のケースを想定します。

1. ルートドメイン（example.com）とサブドメイン（www.example.com）のどちらからアクセスがあっても、ルートドメインにリダイレクトし検索インデックスを統一させたい
2. http,https を区別せずに目的のサイトに到達させたい
3. 特定のパスのみ、別のバックエンドを参照したい


このとき、Amazon S3のウェブサイトホスティングを使う方法が、サーバーレスで組むのに最も良い方法であり、AWSの公式ドキュメントでも紹介があります。
[例: 独自ドメインを使用して静的ウェブサイトをセットアップする](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html)

一見、直感的な構築方法ではないように思えたため、こちらを深掘りしていきたいと思います。

## 1. ドメインのリダイレクト設定
公式ドキュメントを要約すると `S3バケットを2つ用意して、片方はリダイレクトのみを担当、もう片方にコンテンツを配置する` という方法を紹介しています。

![s3_redirection (2) (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/af7b222a-4c19-5bc2-82de-24bc6ceb3e49.jpeg)

リダイレクト用のS3は空のバケット、つまりコンテンツを置く必要がないというのが珍しい使い方のようにみえるのですが、サーバーレスでの環境構築と考えるととても有用でした。

S3の各設定は以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/80169103-60d1-6726-a542-f43039245b7d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/917d830a-b0cb-4d9e-3ff4-a50113bea05b.png)

Route53上での、S3バケットへのaliasレコードの発行、S3のリダイレクトの挙動詳細については、こちらのqiitaがとても参考になりましたのでリンクしておきます。

[Route53 で S3 バケットへ alias レコードを作った際のリダイレクトのふるまい](https://qiita.com/gomi_ningen/items/c2ed285012e38e05fce5)

## 2. http, httpsのリダイレクト設定
ここからが拡張その１です。
S3のウェブサイトホスティングは、httpのみしかサポートしないため、https化するためにはそのフロントにリダイレクト役が必要になります。
ここでは、CloudFrontを使用したパターンを考えてみました。
![s3_CF_redirection (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/2abc411d-3697-7e3b-c162-2d0d63d0d133.jpeg)

ポイントは、CloudFrontの `Viewer Porotocol Policy` で、サブドメイン側のCFは`HTTP and HTTPS`を許容し、ルートドメイン側のCFでは `Redirect HTTP to HTTPS` により、リダイレクトをかけることです。

<img width="1356" alt="Screen Shot 2020-02-21 at 12.31.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/81ce7f43-bb3f-9edf-4cc5-58007ff604b1.png">

<img width="1352" alt="Screen Shot 2020-02-21 at 12.33.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/78eeb536-f031-beb7-d110-e7e44e62196a.png">

## 3. 特定のパスのみ、別のバックエンドを参照
仮に、`/media/*` のパスのみEC2のインスタンスを参照したいケースを考えます。
2の延長で、フロントのCFのパスパターン振り分けにより、特定パスのみALBを参照します。
![s3_CF_ALB_redirection.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/22e0a6ee-8714-f19a-b92d-dcbc0adad14f.jpeg)

<img width="1344" alt="Screen Shot 2020-02-21 at 16.30.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/f8ce32c1-81fc-51d0-acc7-5d78233ab448.png">

### といいつつ冗長な気もする...
サブドメインおよびプロトコルのリダイレクト処理をフロントに任せているため、ALBがいるにも関わらずS3,CFともに2つずつ必要なのがtoo muchな気もします。アクセスが増えれば増えるほど、リダイレクト時の転送量も大きくなります。

そこで、ALBにリダイレクト処理を一任する方法も考えてみました。

![CF_ALB_redirection (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/23da1eab-2020-615e-f251-7e70ec055403.jpeg)


こうすることにより、S3,CFを1つずつ減らすことができました。

1つ注意点は、`ALBの振り分けバックエンドとしてS3のaliasを指定できない` ことにより、新たに `/lp/*` の振り分けをCFで指定し、S3へと飛ばす必要がある点です。
S3のディレクトリ構成に多少変更が必要なのと、パスが変わってしまうことを許容できるのであれば、この方法のほうがよさそうです。

<img width="1352" alt="Screen Shot 2020-02-21 at 21.23.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/44d710b2-17c7-e975-6ae2-6c21e397d5d6.png">
<img width="1287" alt="Screen Shot 2020-02-21 at 21.26.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18022/d2c51b45-e17d-ee7a-10ba-a7d902bdb34b.png">

## まとめ
ランディングページやオウンドメディア を1つのドメインで提供する際の、振り分け設定を考えてみました。
CloudFrontは1つ設定を変えるだけで浸透に数分~数十分かかるため、なかなかトライアンドエラーに時間がかかるため、図示してよく考えてから設定することをおすすめします。