S3静的ウェブサイトホスティング機能でサイトを公開する

目次

S3静的ウェブサイトホスティング機能でサイトを公開する構成

S3の静的ウェブサイトホスティング機能を使って、ウェブサイトを公開する方法を確認します。

ウェブサイトがHTMLやCSS、JavaScriptといった静的コンテンツのみで構成される場合、S3 静的ウェブサイトホスティング機能を使って、サイトを公開することができます。

Amazon S3 を使用して、静的ウェブサイトをホストできます。静的ウェブサイトでは、個々のウェブページの内容は静的コンテンツです。ほかに、クライアント側スクリプトが含まれていることもあります。

Amazon S3 を使用して静的ウェブサイトをホスティングする

構築する環境

Diagram of publishing your site with S3 static website hosting with CloudFormation

S3バケットを1つ作成します。同バケットの静的ウェブサイトホスティング機能を有効化します。

HTMLファイルを設置し、インターネット経由でHTTPアクセスを試みます。今回の検証では、以下の挙動を実現する構成を目指します。

  • ルートページ:バケット内に配置したindex.htmlを表示する
  • エラーページ:バケット内に配置したerror.htmlを表示する
  • リダイレクト:URLのプレフィックスが「/s3/」の場合、「aws.amazon.com」にリダイレクトする

環境構築用のCloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。

以下のURLにCloudFormationテンプレートを配置します。

https://github.com/awstut-an-r/awstut-fa/tree/main/011

テンプレートファイルのポイント解説

今回の環境を構成するための、各テンプレートファイルのポイントを取り上げます。

WebsiteConfigurationで静的ウェブサイトホスティング機能を有効化する

fa-011.yamlでS3関係のリソースを定義します。

Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${Prefix}-bucket"
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false
      WebsiteConfiguration:
        ErrorDocument: error.html
        IndexDocument: index.html
        RoutingRules:
          - RoutingRuleCondition:
              HttpErrorCodeReturnedEquals: '404'
              KeyPrefixEquals: s3/
            RedirectRule:
              HostName: aws.amazon.com
Code language: YAML (yaml)

WebsiteConfigurationプロパティを設定することで、静的ウェブサイトホスティング機能を有効化します。

IndexDocumentおよびErrorDocumentプロパティで、ルートページおよびエラー発生時に表示するページを指定します。先述の通り、それぞれindex.html、error.htmlを表示するように設定します。

RoutingRulesプロパティでリダイレクトに関する設定を行うことができます。今回はURLのプレフィックスが「/s3/」で、HTTPコードが404の場合に、ホスト名が「aws.amazon.com」の同様のURLにリダイレクトするように設定しています。

バケットポリシーでコンテンツへのアクセスを許可する

続いてバケット内のコンテンツに対するアクセス権限の設定を確認します。

Resources:
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Statement:
          Action:
            - s3:GetObject
          Effect: Allow
          Resource: !Sub "arn:aws:s3:::${S3Bucket}/*"
          Principal: "*"
Code language: YAML (yaml)

バケット本体およびバケット内のオブジェクトに対するアクセスは、ACLまたはバケットポリシーで制御することができます。

今回はバケットポリシーを使用してアクセス制御を行います。バケットポリシーはIAMポリシーに基づいた記法でアクセス制御を定義することができます。

バケットポリシーを作成して設定して、Amazon S3 リソースにアクセス許可を付与できます。バケットポリシーは、JSON ベースのアクセスポリシー言語を使用しています。

バケットポリシーの使用

今回はバケット内の全コンテンツを公開するように設定します。Resourceプロパティにてワイルドカード(*)を使用して、本バケット内の全コンテンツを指定します。Principalプロパティでもワイルドカード(*)を使用し、全アクセス元を対象とします。ActionおよびEffectプロパティで「s3:GetObject」と「Allow」とすることで、バケット内コンテンツの読み込みを許可します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成する

CloudFormationスタックを作成します。

スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

スタック内のリソースを確認した結果、今回作成された主要リソース情報は以下の通りです。

  • バケット名:fa-011-bucket

バケットにファイルを設置する

次にHTMLファイルをバケットに配置します。

ファイルの配置はAWS CLIから実行します。

$ aws s3 cp ./html s3://fa-011-bucket/ \
--recursive
upload: html/index.html to s3://fa-011-bucket/index.html
upload: html/error.html to s3://fa-011-bucket/error.html
Code language: Bash (bash)

正常に設置することができました。

AWS Management Consoleからファイルの設置状況を確認します。

S3 for HTML files to be published.

確かに2ファイルが設置されていることがわかります。

ホスティングされたサイトにアクセスする

準備が整いましたので、実際にサイトにアクセスします。

静的ウェブサイトホスティング機能を使って構成されたサイトへのアクセスは、ウェブサイトエンドポイントを通じて行います。

バケットを静的ウェブサイトとして設定すると、そのウェブサイトは、バケットの AWS リージョン 固有のウェブサイトエンドポイントで利用できます。 (中略) 使用しているリージョンに応じて、Amazon S3 ウェブサイトエンドポイントは以下の 2 つの形式のいずれかになります。
s3-website ダッシュ (-) リージョン ‐ http://bucket-name.s3-website-Region.amazonaws.com
s3-website ドット (.) リージョン ‐http://bucket-name.s3-website.Region.amazonaws.com

ウェブサイトエンドポイント

東京リージョン(ap-northeast-1)の場合、上記のダッシュリージョンに該当します。

今回のバケットの場合、以下のURLとなります。

http://fa-011-bucket.s3-website-ap-northeast-1.amazonaws.com

正常ページ

ブラウザで実際にアクセスします。

Accessing a public Web site.

正常にアクセスできました。指定通り、ルートページとして、index.htmlが返ってきました。

エラーページ

次にワザと存在しないコンテンツにアクセスを試み、エラーを発生させます。

Access the error page.

error.htmlが返ってきました。こちらも指定通りです。

リダイレクト

最後にリダイレクトを確認します。
以下のURLにアクセスを試みます。

http://fa-011-bucket.s3-website-ap-northeast-1.amazonaws.com/s3/

When you access a specific URL, you will be redirected.

AWSのS3ページが表示されました。正常にリダイレクトされていることがわかります。

REST API エンドポイント経由でアクセスする

先ほどはウェブサイトエンドポイント経由でサイトにアクセスしましたが、REST API エンドポイント経由でもアクセスすることができます。

Amazon S3 エンドポイントは、以下の構造に従います。
s3-accesspoint.Region.amazonaws.com

REST API を使用したリクエストの実行

今回のバケット場合、以下のようにコンテンツにアクセスすることができます。

Accessing HTML files published in REST API format.

ウェブサイトエンドポイントREST API エンドポイントの違いは「ウェブサイトエンドポイントと REST API エンドポイントの主な違い」をご確認ください。

ACLでアクセス制御する場合

今回はバケットポリシーを使ってアクセス権限を設定しましたが、ACLを使用することでも同様の設定を行うことができます。

Amazon S3 のアクセスコントロールリスト (ACL) では、バケットとオブジェクトへのアクセスを管理できます。各バケットとオブジェクトには、サブリソースとして ACL がアタッチされています。これにより、アクセスが許可される AWS アカウント またはグループと、アクセスの種類が定義されます。

アクセスコントロールリスト (ACL) の概要

ACLにて静的ウェブサイトホスティング用のアクセス権限を行う場合、バケット本体とバケット内部のオブジェクトに対してACLを設定する必要があります。

以下がバケット本体に対するACL設定例です。

Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "${Prefix}-bucket"
      #AccessControl: Private
      AccessControl: PublicRead
Code language: YAML (yaml)

バケット本体に対してコンテンツ公開用の既定ACLを指定します。既定ACLはさまざまな用途に合わせ、予め用意されているACLのことです。

Amazon S3 では、既定 ACL と呼ばれる事前定義済みの一連の許可がサポートされています。各既定 ACL には、あらかじめ定義された一連の被付与者とアクセス権限が含まれています。

既定 ACL

今回はAccessControlプロパティに「PublicRead」を指定することで、バケットに対して全ユーザーに読み込み権を付与するpublic-readを適用します。

以下がバケットに対してACLを設定した結果です。

Make sure that the S3 bucket is publicly exposed by the ACL.

続いてオブジェクトに対するACL設定例です。

$ aws s3api put-object-acl \
--bucket fa-011-bucket \
--key index.html \
--acl public-read

$ aws s3api put-object-acl \
--bucket fa-011-bucket \
--key error.html \
--acl public-read
Code language: Bash (bash)

こちらでも2オブジェクトに対して、全ユーザーに読み込み権を付与するpublic-readを適用します。

以下がファイルに対してACLを設定した結果です。

Make sure that the HTML file is publicly exposed by the ACL.

以上の通り、バケット本体とオブジェクトに対して適切なACLを設定することで、バケットポリシーと同様の挙動を実現することができます。

まとめ

S3 静的ウェブサイトホスティング機能を使って、ウェブサイトを公開する方法を確認しました。

バケット本体やコンテンツへのアクセス権限はバケットポリシーまたはACLを使用することで設定できることを確認しました。

目次