S3で静的WEBサイトを立ち上げようとしたら403(404)エラーが出て困った話

2022.01.14

どうもさいちゃんです。今回はCloudFrontのテストのためにS3の静的ウェブサイトホスティングを使ってテストサイトを立ち上げたっかったので久々に試してみたらさっそく403エラーが出てハマってしまったので、ハマった部分をまとめてみました。

S3の概要

S3はAWSの提供するストレージサービスです。あらゆるデータを安全に保存することができるのですが、機能の一つに静的ウェブサイトのホスティングというものがあります。

S3バケットにhtmlファイルなどをアップロードしてWEBサイトとして閲覧できるようにすることができる機能です。

今回はハマった部分だけをまとめてみたので、詳しいホスティングの方法はこちらをご覧ください。

ハマったところ

バケットを作ってファイルをアップロードして、静的WEBコンテンツの有効化をしてさぁOK!と思ってURLに飛んでみたら見事に403(404)エラーが出てきました。

  • 403エラー(Forbidden)
    何らかの原因でユーザーがサイトの閲覧を禁止されている際に出るエラー表示です。アクセス権がない場合などに表示されます。
  • 404エラー(No Found)
    ページが見つからない(存在しない)場合に出るエラーになります。

こうなってしまった原因がいくつかあったのでまとめてみました。

ブロックアクセスリストの設定

403エラーの原因はいろいろあったのですが、まずはブロックアクセスリストでした。

アクセス許可からブロックパブリックアクセス (バケット設定)の編集に進むと下記の画面が出てきます.

うっかりこのチェックボックスのチェックを外し忘れていたんですね。

チェックをつけたままだと、パブリックにアクセスすることができなくなってしまいますので、すべてのチェックリストからチェックが外れていることを確認して変更を保存します。

こちらのチェックを外すと警告のポップアップが出てきますが、今回はバケットの中身を公開したいので、確認と打ち込んで大丈夫です。

ただ、これでも引き続きエラーが出てます。

バケットポリシーの設定

次に変更したのは、バケットポリシーです。

引き続きアクセス許可の項目からバッケトポリシーを確認します.

AWSへのアクセスはデフォルトですべて拒否されているのでバケットポリシーを下記のように変更してあげます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::バケット名/*"
        }
    ]
}

バッケト名の部分を自身が作成したS3バケット名に変更をして保存します。

バケットポリシーの変更が完了したので、再度ページにアクセスをしてみると、

今度は404エラーが出てきました。インデックスドキュメント名も合っているし、調べた限りの解決策を試してみたのになんで、、と思ってたら原因は他にありました。

フォルダごとアップロードしていました

このバケットに「index.html」をアップロードすれば良かったんですが、今回のテストサイトは画像データやCSSデータの入ったフォルダにまとめてそのまま「forS3」というフォルダをアップロードしていたんですね。

バケットにフォルダをアップロードすることは可能なんですが、AWSの公式ドキュメントによると

Amazon S3 では、バケットはオブジェクトのフラットコンテナです。つまり、コンピュータのファイルシステムとは異なり、階層構造ではありません。ただし、論理的な階層を作成するには、フォルダ構造を暗示させる名前をオブジェクトキーに付けます。

フォルダ構造をバケット内に作成する場合は、各レベルにインデックスドキュメントが存在している必要があります。各フォルダでは、インデックスドキュメントは同じ名前 (index.html など) であることが必要です。

ということで、フォルダごとバケットにアップロードすると「index.html」の場所を明示的に指定しないといけなくなるようでした。

そこで、再度「forS3」の中身だけをバケットにアップロードしました。

ここでやっとサイトにアクセスすることに成功しました!

フォルダのままでサイトを表示させたい

バケットサイトエンドポイントは、

http://バッケト名.s3-website.リージョン.amazonaws.com/photos/

という構成になっています。バッケトにアップロードしたフォルダからWEBサイトを表示させたい場合はこのURLの末尾に/フォルダ名を付けてあげることでS3は指定したフォルダの中からindex.htmlを探してくれるようになります。

解決!

やっと解決ができました。S3の静的WEBホスティング使ったことはあったのですが、常時触っていないとやはり忘れてしまうところがありますね。いざ使うときに次回からはハマらないように気を付けます。