CloudFront経由でS3コンテンツを配信する – 静的ウェブサイトホスティング版

CloudFront経由でS3コンテンツを配信する - 静的ウェブサイトホスティング版

CloudFront経由でS3コンテンツを配信する

CDNサービスであるCloudFrontを使用して、S3バケットに配置したコンテンツを配信することができます。
今回は静的ウェブサイトホスティング機能を有効化し、パブリックにアクセス可能なS3バケットを対象とします。

なおOAI(Origin Access Identity)を使用することで、今回の構成と同様の動作を実現するすることもできます。こちらも併せてご確認ください。

あわせて読みたい
OAIを使用してCloudFront経由でS3コンテンツを配信する 【CloudFrontからS3コンテンツを配信する際に、OAIでオリジンへのアクセスを制限する】 以下のページで、S3バケットのコンテンツをCloudFrontから配信する際に、Referer...

構築する環境

Diagram of S3 content delivery via CloudFront - Static website hosting ver

S3バケットを作成し、静的ウェブサイトホスティング機能を有効化します。
バケットポリシーでバケット内のコンテンツを、パブリックに公開するように設定します。

CloudFrontディストリビューションを作成し、バケットをオリジンに設定します。

Lambda関数を作成します。
この関数をCloudFormationカスタムリソースとして設定します。
この関数の働きですが、スタック生成・削除時に、自動的にバケットにオブジェクト生成・削除を実行するように設定します。
生成するオブジェクトは静的ウェブサイトホスティング用のindex.htmlとします。
関数のランタイムはPython3.8とします。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

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

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

本ページはCloudFrontを使用して、S3バケットコンテンツを配信する方法を中心に取り上げます。

S3バケットの静的ウェブサイトホスティング機能については、以下のページをご確認ください。

あわせて読みたい
S3静的ウェブサイトホスティング機能でサイトを公開する 【S3静的ウェブサイトホスティング機能でサイトを公開する構成】 S3の静的ウェブサイトホスティング機能を使って、ウェブサイトを公開する方法を確認します。 ウェブサ...

CloudFormationのカスタムリソースを使用して、スタック生成・削除時に、バケットにオブジェクト生成・削除を実行する方法については、以下のページをご確認ください。

あわせて読みたい
CFNカスタムリソースでS3オブジェクトを作成・削除する 【CloudFormationカスタムリソースを使って、スタック生成/削除時にS3オブジェクトを作成/削除する方法】 CloudFormationカスタムリソースはスタック操作(作成、更新、...

(参考)S3バケットの静的ウェブサイトホスティング

Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref Prefix
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false
      WebsiteConfiguration:
        IndexDocument: index.html

  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument:
        Statement:
          Action:
            - s3:GetObject
          Effect: Allow
          Resource: !Sub "arn:aws:s3:::${Bucket}/*"
          Principal: "*"


Outputs:
  BucketArn:
    Value: !GetAtt Bucket.Arn

  BucketWebsiteURL:
    Value: !GetAtt Bucket.WebsiteURL

  BucketName:
    Value: !Ref Bucket
Code language: YAML (yaml)

ポイントは2点です。

1点目はバケットポリシーです。
バケットポリシーによって、作成するバケットへのパブリックアクセスを許可します。

2点目はバケットから取得するデータです。
今回はバケットウェブサイトURLが重要な値です。
このURLは組み込み関数Fn::GetAttで取得することができます。
後述しますが、CloudFrontのオリジンサーバを指定する際に、このURLの一部を使用します。

以下にバケットウェブサイトURLのサンプルを記載します。

http://[bucket-name].s3-website-[region-name].amazonaws.com

CloudFrontディストリビューション

Resources:
  Distribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        DefaultCacheBehavior:
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
          Compress: true
          ForwardedValues:
            Cookies:
              Forward: none
            QueryString: false
          TargetOriginId: !Ref BucketName
          ViewerProtocolPolicy: allow-all
        Enabled: true
        Origins:
          - DomainName: !Select
              - 2
              - !Split
                  - /
                  - !Ref BucketWebsiteURL
            Id: !Ref BucketName
            #S3OriginConfig:
            CustomOriginConfig:
              OriginProtocolPolicy: http-only
        PriceClass: PriceClass_All
Code language: YAML (yaml)

パブリックに公開しているS3バケットを、CloudFrontのオリジンに設定する上でのポイントを2点取り上げます。

1点目はドメイン名の設定です。
これはDomainNameプロパティに設定します。
静的ウェブサイトホスティング機能を有効化してパブリックに公開しているバケットの場合、バケットウェブサイトエンドポイントのドメイン名を指定します。
先ほどご紹介したバケットウェブサイトURLの「http://」以降の文字列がこれに該当します。
そのため組み込み関数Fn::Selectと同じくFn::Splitを使用して、ドメイン名の箇所を抽出した上で、本プロパティに指定します。

2点目はオリジンの詳細設定に関するプロパティです。
S3バケットをオリジンとする場合、以下の2つのどちらかのプロパティを設定する必要があります。

  • CustomOriginConfig:S3バケットで静的ウェブサイトホスティングを有効化している場合に設定する。
  • S3OriginConfig:S3バケットで静的ウェブサイトホスティングを有効化していない場合に設定する。

今回は有効化していますので、CustomOriginConfigプロパティに設定を行います。
バケットウェブサイトエンドポイントにアクセスする場合、CloudFrontからS3バケット間の通信は、SSL化されていないHTTP通信である必要があります。
ですからOriginProtocolPolicyプロパティで「http-only」を設定します。

環境構築

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

CloudFormationスタックを作成し、スタック内のリソースを確認する

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

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

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

  • S3バケット:fa-048
  • CloudFrontディストリビューションのドメイン:https://d3pnwba2gu8n7s.cloudfront.net

AWS Management ConsoleからもCloudFrontを確認します。

Distribution domain name.

CloudFrontディストリビューションが作成されています。

The s3 bucket is set as the CloudFront origin.

ディストリビューションのオリジンにS3バケットのウェブサイトエンドポイントが設定されています。

動作確認

準備が整いましたので、CloudFrontディストリビューションにアクセスします。

The result of S3 content delivery via CloudFront.

S3バケットのコンテンツが表示されました。
CloudFrontを経由して、オリジンであるS3バケットのウェブサイトエンドポイントにアクセスしているということです。

ちなみにオリジンであるS3バケットに、直接アクセスすることもできます。

Direct access to S3 bucket.

現状の設定では、直接オリジンにアクセスすることを制限する設定を行っていないためです。

まとめ

CloudFrontを使用して、S3バケットに配置したコンテンツを配信することができました。