前回までのあらすじ
第1回では samekorolab.com を取得し、自分のドメインでSAMEKORO LABを開けるところまで進みました。
今回は、その画面が届くまでの裏側です。CloudFrontとS3をどうつなぎ、なぜS3を直接公開しなかったのかを、自分の判断を中心に振り返ります。
最初はS3だけで公開すればいいと思っていた
SAMEKORO LABはHTML、CSS、JavaScript、画像でできた静的サイトです。最初は、S3にファイルを置き、Webサイトとして公開する形が分かりやすいと思っていました。
ただ、独自ドメインとHTTPSを使いながら、S3は外へ直接見せない構成も試してみたくなりました。利用者がアクセスする場所をCloudFrontへまとめたほうが、今回の配信経路を自分で説明しやすいとも考えました。
そこで、S3はファイル置き場にし、公開側はCloudFrontへ任せることにしました。
CloudFrontをサイトの入口にした
サービスを一つ増やすぶん複雑になるのでは、と少し迷いました。それでも、入口をCloudFrontへまとめれば、守りたい境界を説明しやすくなります。必要なファイルはS3から取得し、独自ドメインとHTTPSもここで受けます。
イメージとしては、CloudFrontが入口、S3が奥の倉庫です。比喩は単純ですが、自分がどちらを公開し、どちらを閉じたいのかが分かりやすくなりました。
公開経路をCloudFrontへ寄せ、S3を非公開にする。その目的に合うかどうかで構成を決めました。
OACでCloudFrontからだけS3へアクセスさせる
S3を非公開のまま使うため、OAC(=CloudFrontからだけS3へアクセスさせる仕組み)を設定しました。
CloudFrontがS3へリクエストするときに署名を付け、そのアクセスだけをS3側で許可します。バケットのパブリックアクセスはブロックしたままです。
OACを作ってCloudFrontへ関連付けたところで、いったん「これで通るはず」と思いました。実際は、どのCloudFrontディストリビューションから、どのオブジェクトを取得してよいか、S3のバケットポリシーにも許可を書く必要があります。片側だけではつながらないことに、ここで気づきました。
今回の構成
設定画面を行き来していると全体を見失いそうになったので、今回組んだ流れを図にしました。
利用者はHTTPSで samekorolab.com を開きます。Route 53がCloudFrontへ案内し、CloudFrontはOAC経由で非公開S3バケットからファイルを取得します。ACMの証明書はCloudFrontへ設定しています。
図へ戻って眺めると、S3は公開経路にいないことがはっきりします。CloudFrontまたは独自ドメインからは表示でき、S3のオブジェクトURLへ直接アクセスしても拒否される。この両方を確認できて、ようやく狙った形になったと感じました。
S3の静的Webサイトホスティングは使わなかった
今回は、S3の静的Webサイトホスティングを有効にしていません。CloudFrontのオリジンには、通常のS3バケットエンドポイントを指定しています。
CloudFrontのDefault Root Object(=CloudFrontディストリビューションのルートURLへアクセスした際に返すファイル)には index.html を設定しました。これは配信ドメインのルートURL向けの設定で、記事のような下層URLへ自動的に index.html を補うものではありません。
そのため現在の記事リンクは、articles/<slug>/index.html まで含めています。二つを同じ仕組みだと思っていたので、実際のURLを試して違いが分かりました。
バケットポリシーでCloudFrontだけを許可した
OACを関連付けたあと、バケットポリシー(S3バケットへのアクセス許可を決める設定)を追加しました。見るポイントは次の3つです。
- CloudFrontのサービスに
- S3オブジェクトの取得を
- このサイトの対象ディストリビューションからだけ許可する
最初にJSON全体を眺めたときは少し身構えました。ただ、許可する相手・操作・対象へ分けると、何を通そうとしているのか追えるようになりました。実際のアカウントIDやARNは記事には載せません。
設定途中で403エラーが出た
設定の途中では、403エラー(=アクセスを拒否された状態)が出ました。S3を閉じた結果なのか、CloudFrontからの道を作り切れていないのか、ここで少し迷いました。どこかの許可がつながっていなければ表示できません。
当時の記録だけでは、原因を一つに特定できていません。確認候補として残しているのは、OACの関連付け、バケットポリシーの対象、S3オリジン、オブジェクトキー、Default Root Objectです。
早く直したくて設定を足したくなりましたが、原因を決めつけず、CloudFrontからS3までを順にたどるほうが確実でした。
狙った構成になっているか確認した
設定後は、今回の環境で実際にアクセスして確認しました。
- CloudFrontのURLからサイトを表示できる
samekorolab.comからも同じサイトを表示できる- S3オブジェクトURLへ直接アクセスすると拒否される
CloudFront経由で画面が出たときは、まずほっとしました。そのあとS3へ直接行くと見えないことも確認し、二つがそろって初めて狙った状態だと判断できました。
個人サイトには少し大げさ。でも今回はこれでよかった
最短で公開することより、自分で公開経路をつなぎ、確かめることを優先しました。S3を直接見せず、入口を一つにしたいという判断には合っています。
公開後には、記事カードのリンクが articles/<slug>/ で終わっていたため、下層の index.html が自動では返らず404になりました。リンクを articles/<slug>/index.html へ直して解消しています。詳しい切り分けは、別のトラブル解決記事にできそうです。
設定画面だけでなく、実際のURLまで見る必要があると、ここでも分かりました。
まとめ
SAMEKORO LABは、CloudFrontを公開側に置き、OAC経由で非公開S3から配信する構成にしました。S3への直接アクセスが拒否されることも確認しています。
構成要素は増えましたが、公開する経路と閉じる場所を自分の目的から決められたので、今回はこの形でよかったです。
次回は、公開前の記事まで見えてしまい、サイトの公開範囲を見直した話を書きます。