CloudFront を使用して、Amazon S3 でホストされた静的ウェブサイトを公開するにはどうすればよいですか?

最終更新日: 2021 年 1 月 5 日

静的ウェブサイトを Amazon Simple Storage Service (Amazon S3) バケットでホスティングし、Amazon CloudFront ディストリビューションを通じてウェブサイトを公開したいと考えています。どうすればそれができますか?

簡単な説明

Amazon S3 でホストされている静的ウェブサイトを公開するには、次のいずれかの設定を使用して CloudFront ディストリビューションをデプロイできます。

  • アクセスがオリジンアクセスアイデンティティ (OAI) で制限されたオリジンとして、REST API エンドポイントを使用する
  • 匿名 (パブリック) アクセスを許可して、ウェブサイトのエンドポイントをオリジンとして使用する
  • アクセスが Referer ヘッダーで制限されたオリジンとして、ウェブサイトのエンドポイントを使用する
  • AWS CloudFormation を使用して REST API エンドポイントをオリジンとしてデプロイし、OAI と CloudFront を指すカスタムドメインによってアクセスを制限する

2 つのエンドポイントタイプの詳細については、ウェブサイトエンドポイントと REST API エンドポイントの主な相違点を参照してください。

解決方法

オリジンとして使用する S3 エンドポイントタイプを利用して、CloudFront ディストリビューションを設定する手順通りに実行します。

OAI によってアクセスが制限されているオリジンとして REST API エンドポイントを使用する

  1. Amazon S3 コンソールを使ってバケットを作成し、ウェブサイトファイルをアップロードします。
    注: この設定では、バケットで静的ウェブサイトホスティングを有効にする必要はありません。この設定では、静的ウェブサイトホスティング機能のウェブサイトエンドポイントではなく、バケットの REST API エンドポイントを使用します。
  2. CloudFront ウェブディストリビューションを作成します。ユースケースに必要なディストリビューション設定に加えて、以下を入力してください。
    [Origin Domain Name] には、作成したバケットを選択します。
    [バケットアクセスの制限] には、[はい] を選択します。
    [Origin Access Identity] には、[新しい ID の作成] を選択します。
    [コメント] には、デフォルト値のままを選択することができます。または、OAI のカスタムラベルを入力することもできます。
    [バケットの読み取りアクセス許可を付与] には、[はい、バケットポリシーを更新します] を選択します。
  3. ウェブサイトには SSL (HTTPS) を使用するのがベストプラクティスです。SSL を設定するには、[SSL 証明書] で [デフォルトの CloudFront 証明書] を選択して、デフォルトの CloudFront DNS 名を使用します。または、[カスタム SSL 証明書] を選択して、独自のカスタムドメインを使用します。[ACM で証明書をリクエストまたはインポート] を選択して、新しい証明書をリクエストすることもできます。
    重要: ディストリビューションに [Alternate domain names (CNAMEs)] (代替ドメイン名 (CNAME)) を入力した場合、CNAME は選択した SSL 証明書と一致する必要があります。SSL 証明書の問題をトラブルシューティングするには、CloudFront ディストリビューションでカスタム SSL 証明書を使用している場合の問題のトラブルシューティング方法を教えてくださいをご覧ください。
  4. [ディストリビューションを作成] をクリックします。
  5. ドメインの DNS レコードを更新して、ウェブサイトの CNAME を CloudFront ディストリビューションのドメイン名に設定します。CloudFront コンソールd1234abcd.cloudfront.net のような形式のディストリビューションのドメイン名を見つけることができます。
  6. DNS の変更が反映され、以前の DNS エントリが期限切れになるまで待ちます。
    注: 以前の DNS 値の有効期限が切れるまでにかかる時間は、ホストゾーンで設定されている TTL 値、およびローカルのリゾルバーがこれらの TTL 値を使用するかどうかによって異なります。

匿名 (パブリック) アクセスを許可して、ウェブサイトのエンドポイントをオリジンとして使用する

この設定では、ウェブサイトのバケットに対するパブリック読み取りアクセスが許可されます。詳細については、ウェブサイトへのアクセスに必要な権限を参照してください。

注: Amazon S3 静的ウェブサイトエンドポイントを使用する場合、CloudFront と Amazon S3 間の接続は HTTP 経由でのみ行えます。CloudFront と Amazon S3 間の接続に HTTPS を使用するには、オリジンに S3 REST API エンドポイントを設定します。

  1. Amazon S3 コンソールを使用してバケットを作成し、このバケットで静的ウェブサイトのホスティングを有効にします
  2. [静的ウェブサイトホスティング] ダイアログボックスから、バケットのエンドポイントをコピーします (先頭の http:// は除きます)。形式は DOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com のようになります。後のステップで、この形式のエンドポイントが必要になります。
  3. 作成したバケットへパブリック読み取りアクセスを許可するバケットポリシーを追加します。
  4. CloudFront ウェブディストリビューションを作成します。ユースケースに必要なディストリビューション設定に加えて、以下を入力してください。
    [オリジンドメイン名] に、ステップ 2 でコピーしたエンドポイントを入力します。
  5. ウェブサイトには SSL (HTTPS) を使用するのがベストプラクティスです。SSL を設定するには、[SSL 証明書] で [デフォルトの CloudFront 証明書] を選択して、デフォルトの CloudFront DNS 名を使用します。または、[カスタム SSL 証明書] を選択して、独自のカスタムドメインを使用します。[ACM で証明書をリクエストまたはインポート] を選択して、新しい証明書をリクエストすることもできます。
    重要: ディストリビューションに [代替ドメイン名 (CNAME)] を入力した場合、CNAME は選択した SSL 証明書と一致する必要があります。SSL 証明書の問題をトラブルシューティングするには、CloudFront ディストリビューションでカスタム SSL 証明書を使用している場合の問題のトラブルシューティング方法を教えてくださいをご覧ください。
  6. [ディストリビューションを作成] をクリックします。
  7. ドメインの DNS レコードを更新して、ウェブサイトの CNAME を CloudFront ディストリビューションのドメイン名に設定します。CloudFront コンソールd1234abcd.cloudfront.net のような形式のディストリビューションのドメイン名を見つけることができます。
  8. DNS の変更が反映され、以前の DNS エントリが期限切れになるまで待ちます。
    注: 以前の DNS 値の有効期限が切れるまでにかかる時間は、ホストゾーンで設定されている TTL 値、およびローカルのリゾルバーがこれらの TTL 値を使用するかどうかによって異なります。

アクセスが Referer ヘッダーで制限されたオリジンとして、ウェブサイトのエンドポイントを使用する

この設定では、ディストリビューションにカスタムの Referer ヘッダーを設定し、次にバケットポリシーを使用してカスタムの Referer ヘッダーを持つリクエストにのみアクセスを許可することで、アクセスを制限します。この設定で許可されているアクセスが、ユースケースの要件を満たしているかどうかを必ず評価してください。

注: Amazon S3 静的ウェブサイトエンドポイントを使用する場合、CloudFront と Amazon S3 間の接続は HTTP 経由でのみ行えます。CloudFront と Amazon S3 間の接続に HTTPS を使用するには、オリジンに S3 REST API エンドポイントを設定します。

  1. Amazon S3 コンソールを使用してバケットを作成し、このバケットで静的ウェブサイトのホスティングを有効にします
  2. [静的ウェブサイトホスティング] ダイアログボックスから、バケットのエンドポイントをコピーします (先頭の http:// は除きます)。形式は DOC-EXAMPLE-BUCKET.s3-website-region.amazonaws.com のようになります。後のステップで、この形式のエンドポイントが必要になります。
  3. CloudFront ウェブディストリビューションを作成します。ユースケースに必要なディストリビューション設定に加えて、以下を入力してください。
    [Origin Domain Name] で、手順 2 でコピーしたエンドポイントを入力します。
    [ヘッダー名] の [Origin カスタムヘッダー] に、[Referer] と入力します。[] には、オリジンに転送するカスタムヘッダーを入力します (S3 バケット)。オリジンへのアクセスを制限するために、ランダムな値または他の人は知らない秘密の値を入力することができます。
  4. ウェブサイトには SSL (HTTPS) を使用するのがベストプラクティスです。SSL を設定するには、[SSL 証明書] で [デフォルトの CloudFront 証明書] を選択して、デフォルトの CloudFront DNS 名を使用します。または、[カスタム SSL 証明書] を選択して、独自のカスタムドメインを使用します。[ACM で証明書をリクエストまたはインポート] を選択して、新しい証明書をリクエストすることもできます。
    重要: ディストリビューションに [代替ドメイン名 (CNAME)] を入力した場合、CNAME は選択した SSL 証明書と一致する必要があります。SSL 証明書の問題をトラブルシューティングするには、CloudFront ディストリビューションでカスタム SSL 証明書を使用している場合の問題のトラブルシューティング方法を教えてくださいをご覧ください。
  5. [ディストリビューションを作成] をクリックします。
  6. Amazon S3 コンソールからウェブサイトのバケットを開きます。次に、手順 3 で指定したカスタム Referer ヘッダーがリクエストに含まれることを条件として、s3:GetObject を許可するバケットポリシーを追加します。
    注: カスタム Referer ヘッダーを含まないリクエストに対するアクセスをブロックするには、バケットポリシーで明示的な拒否ステートメントを使用します。
  7. ドメインの DNS レコードを更新して、ウェブサイトの CNAME が CloudFront ディストリビューションのドメイン名をポイントするように設定します。CloudFront コンソールd1234abcd.cloudfront.net のような形式のディストリビューションのドメイン名を見つけることができます。
  8. DNS の変更が反映され、以前の DNS エントリが期限切れになるまで待ちます。
    注: 以前の DNS 値の有効期限が切れるまでにかかる時間は、ホストゾーンで設定されている TTL 値、およびローカルのリゾルバーがこれらの TTL 値を使用するかどうかによって異なります。

CloudFormation を使用して REST API エンドポイントをオリジンとしてデプロイし、OAI と CloudFront を指すカスタムドメインによってアクセスを制限する

このソリューションを使用すると、ウェブサイトは次のようになります。

  • CloudFormation でデプロイされる
  • Amazon S3 でホストされる
  • CloudFront によって配信される
  • AWS Certificate Manager (ACM) の SSL/TLS 証明書を使用します。
  • Lambda@Edge を使用して、すべてのサーバーレスポンスにセキュリティヘッダーを追加する

このソリューションをデプロイする手順については、GitHub ウェブサイトの Amazon CloudFront Secure Static Website を参照してください。