S3 + CloudFrontでSPAサイトを提供する設定
最近、普段アプリケーションの開発ばかりをやっており、久々にAWS関連の構築をやろうとすると、結構忘れてる事あるなーと思い今回備忘録として残しました。 特にドメインやCDN周りの設定等、頻繁にはやることはないかと思うので、また忘れたときに見直せればいいかなと
設定項目
以下の順に設定することを推奨します。
- ドメイン登録
- Route53設定
- S3バケット作成
- AWS Certificate Manager(ACM)証明書リクエスト
- CloudFrontディストリビューション作成
- CloudFrontにSSL証明書を登録
- S3バケットのポリシーを確認
- Route53にCloudFrontのドメインを設定
- S3にアップロード
構成
ドメイン登録
すでに他のドメインでも利用しており、支払いの関係上、今回はお名前で登録しました。 ここに関しては、説明は省きます。各サービスの手順通りに進めていくだけなので。
Route53設定
ホストゾーン作成
Route53 > ホストゾーンの作成
- 登録済みのドメイン名でホストゾーンを作成します。
作成したホストゾーンのNSレコードをドメイン提供サービス側(今回の場合はお名前)に設定します。
- *お名前の場合 : ネームサーバー設定 > ネームサーバー変更から、設定するドメインをチェック入れて、選択し、ネームサーバー情報の入力欄にRoute53のNSレコードを1つずつ入力し、確認画面へ進んで保存します。(毎回思うけど、ここのcheckboxのUIが非常に分かりづらい...)
$ whois <domain name>
- DNSの復習は以下を参考
S3バケット作成
S3 > バケットを作成する
- 名前とリージョン : バケット名を入力しとリージョンを選択します
- オプションの設定 : デフォルトで大丈夫です。(アクセスログ等は必要に応じて設定してください。)
- アクセス許可の設定 : パブリックアクセスをすべてブロックにチェックが入っている場合、外しておきます
- 確認 : 問題なければ保存します。
- 作成したバケットのプロパティから
Static website hosting
を選択し、"このバケットを使用してウェブサイトをホストする"を選択後、"インデックスドキュメント"にindex.html
と入力し保存します。
ACM証明書リクエスト
* リージョンは必ずバージニア北部にしておくこと(CloudFrontからのACM利用はバージニア北部しか対応していないため)
Certificate Manager > 証明書のリクエスト
- ドメイン名 : ワイルドカード指定でドメイン名入力します。(最終的なアクセスとして、wwwでアクセスするため、サブドメインも登録しちゃいます)
- 検証方法 : DNSを選択し、確認とリクエストを送信します。
- 検証ページのドメイン名をクリックして、"Route 53 でのレコードの作成"をクリックしてDNSレコードを作成します。
- 検証完了するまで待ちます
CloudFrontディストリビューション作成
CloudFront Distributions > Create Distribution
- WebでGet Startedで次に進みます
- Origin settings
- Default Cache Behavior Settings
- Distribution Settings
SPAサイトでのリダイレクト対応
ルーティングをSPAでやる場合(React Routing等)、静的コンテンツが存在しない為、Webサーバにデプロイした場合、基本的には404(S3バケットの場合403)になるはずです。
nginxだと、rewrite
ディレクティブで制御出来ますが、それと同じようなことをCloudFrontでやる例が以下になります。
- 作成したディストリビューションを選択し、Error Pagesのタブに遷移します
Create Custom Error Responseをクリックし、ルールを追加します
HTTP Error Code : 403
- Customize Error Response : Yes
- Response Page Path : index.html
- HTTP Response Code : 200
S3バケットのポリシー確認
CloudFrontのオペレーションにより以下のように作成されていれば大丈夫です。
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <CloudFront Distribution ID>" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::bucket/*" } ] }
Route53にCloudFrontのドメインを設定
Route53 > ホストゾーン選択 > レコードセットの作成
上記の設定でレコードを保存
S3にアップロード
* 今回特にReact Router等については一切触れないので、すでにビルド済みのコンテンツが存在することとします
実際にアクセスして確認
React Router等のJSルーティングでのページ遷移でリロードしても正常に動作すれば成功です。