CloudFront + S3 構築のポイント

1月 6, 2021AWS,CloudFront,S3

概要

  • 今回は、CloudFront + Amazon S3 構成を構築する際のポイントをまとめます。CloudFront + Amazon S3 は典型的な構成でもあり、デフォルトの設定でも動作しますが、いくつか押さえておきたいポイントがあります。

 

S3 へのアクセス制限を設定する

  • CloudFront OAIを作成して、ユーザーは S3 バケットへ直接アクセスではなく、CloudFront 経由でのみアクセスできるようにします。前提として、S3の静的ウェブサイトホスティングは"無効"とします。
  • もし、S3の静的ウェブサイトホスティングを"有効"とする場合は、CloudFront OAIによるアクセス制限は使えません。オリジンはバケットウェブサイトエンドポイントを指定したカスタムオリジンで登録し、カスタムヘッダーでアクセス制限を行う必要があります。詳細は、こちらを参照。
  • CloudFront のディストリビューションを作成する際、先ずオリジンを設定します。Origin Domain NameにS3 のバケット名を指定します。
  • 次に、Restrict Bucket Accessを"Yes" とします。Origin Access Identityを"Create a New Identity" とし、CommentにOAI の名前を指定します。
  • 次に、Grant Read Permissions on Bucketを"Yes, Update Bucket Policy" とします。

  • キャッシュ動作を設定します。(静的コンテンツを配信する場合はデフォルトでも問題ありませんが、状況によってカスタマイズが必要です)
  • ディストリビューションの設定を行います。代替ドメイン名を設定する場合は、下記記事を参照ください。

 

  • 以下の通り、ディストリビューションがデプロイされました。

 

  • S3 のバケットポリシーには、以下の様なエントリが追加されました。
  • この設定によって、CloudFrontにオリジンアクセスアイデンティティ(OAI)と呼ばれる特別なユーザーを作成し、CloudFront が OAI を使用してバケット内のファイルにアクセスできるようにS3 バケットのアクセス許可が設定されています。
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1ABCDEFGHIJKL"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::niikawa1/*"
        }

 

  • ブラウザなどからCoudFront のURL にアクセスし、コンテンツが表示されることを確認します。

 

デフォルトのルートオブジェクトを設定

ルート URLのindex.html を返す設定について

  • CloudFrontは、ディストリビューションのURL へアクセスする際に、"index.html"の指定を省略できません。そのため、次は、ルート URL のアクセス時にCloudFrontが"index.html" をオブジェクトとして返す設定を行います。
  • 以下は、CloudFrontのデフォルト設定の動作です。S3の静的ウェブサイトホスティングではデフォルトで"index.html"を返す動作を行いますが、CloudFrontのデフォルト設定の場合は、"index.html" を省略できずオブジェクトの名前まで指定が必要です。

  • 上記課題の対処として、ディストリビューション設定の Default Root Object に"index.html" を指定します。

 

  • ブラウザなどからCoudFront のルートURL にアクセスし、コンテンツが表示されるように変わったことを確認します。

 

サブディレクトリのindex.html を返す設定について

  • 上記に紹介した、ディストリビューション設定の Default Root ObjectはCoudFront のルートURL(例: http://d2nzmh0f3jp7c9.cloudfront.net/)にのみ機能し、サブディレクトリ(例: http://d2nzmh0f3jp7c9.cloudfront.net/subdir/)には機能しません。
  • サブディレクトリのアクセスで、index.html を返すためのインフラ観点の回避方法として、Lambda@Edge を使用する方法があります。Lambda@Edge を使用して、リクエストの URLが / で終わっている場合に末尾に index.html を追加することができます。設定例は、下記、記事を参照ください。
    • デメリットは、Lambda@Edgeを使用すると追加料金が必要となります。利用料については、こちらを参照。
  • インフラ以外の観点では、Lambda@Edgeを使わず、Vue.jsのルーティング設定などSPA(Single Page Application)側で回避する方法もあるようです。

 

 

開発中はキャッシュを保持しない選択肢もあり

キャッシュのTTLを0 に設定する

  • CloudFrontの目的の1つは、エッジサーバーでコンテンツのキャッシングを行いオリジンの負荷を軽減することにあります。しかし、コンテンツの開発中は頻繁に更新を行うため、有効期限(TTL)を"0″にする or 低い値に設定する考慮も必要になります。

 

 

CloudFrontのキャッシュを削除する

  • 前述のキャッシュのTTLを0 に設定する方法以外に、コンテンツを更新後、CloudFrontのキャッシュを削除する方法で対応することも可能です。
  • [Invalidations]タブを開き、[Create Invalidation]を押します。Object Paths にオブジェクトを指定し、[Invalidate]ボタンを押します。削除したいオブジェクトのキャッシュをパスで指定します。以下例の様に、ワイルドカードで指定することも可能です。

 

  • InvalidationのStatusが “In Progress"から"Completed" に変われば、キャッシュの削除は完了です。

 

  • ブラウザなどからCoudFront にアクセスし、コンテンツが更新されたことを確認します。

 

エラーページの対応

  • クライアントから存在しないURL へアクセスがあった場合、CloudFront は以下403のエラーを返します。(This XML file does not appear to have any style information associated with it. )

 

  • 上記デフォルトのエラーではなく、CloudFront からカスタムエラーメッセージを含むオブジェクト(HTML ファイルなど)が返されるように変更できます。
    • サポートされている HTTP ステータスコードに応じて、異なるオブジェクトを返すことができます。または、サポートされているすべてのステータスコードに同じオブジェクトを返すこともできます。
    • CloudFront がカスタムエラーページを返すことのできる HTTP ステータスコードは、以下となります。
      • 400、403、404、405、414、416
      • 500、501、502、503、504
  • [Error Pages]タブを開き、[Create Custom Error Response]を押します。

 

  • “HTTP Error Code"を選択します。今回のケースは、"403: Forbidden"を選択します。
  • “Customize Error Response"に"Yes"、"Response Page Path"に403エラー時に返すオブジェクトのパス、"HTTP Response Code"に返すステータスコード(今回は404)を指定します。

  • HTTPエラーコード 403に対するレスポンスが設定できました。必要に応じて、他のHTTPエラーコードを設定します。

 

  • ブラウザなどからCoudFront にアクセスし、存在しないURLのアクセスでカスタムエラーページが返されることを確認します。

 

 

参考資料