AWS

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

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

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

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

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

構築する環境

Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Diagram of S3 content delivery via CloudFront - Static website hosting ver

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

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

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

CloudFormationテンプレートファイル

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

awstut-fa/048 at main · awstut-an-r/awstut-fa
Contribute to awstut-an-r/awstut-fa development by creating an account on GitHub.

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

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

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スタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

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

  • 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バケットに配置したコンテンツを配信することができました。

タイトルとURLをコピーしました