本ページは、AWS に関する個人の勉強および勉強会で使用することを目的に、AWS ドキュメントなどを参照し作成しておりますが、記載の誤り等が含まれる場合がございます。

最新の情報については、AWS 公式ドキュメントをご参照ください。

CloudFront とは、大容量キャパシティを持つ地理的に分散したサーバー群(エッジロケーション)にコンテンツをキャッシュしたり、代理配信をするコンテンツ配信ネットワーク (CDN(Content Delivery Network)) サービスです。

CDN を導入することによって、ユーザーに一番近いエッジロケーションから配信することによる高速化と、エッジサーバーでコンテンツをキャッシュすることによるオリジンの負荷軽減ができるというメリットがあります。

CloudFront は従量課金のサービスであるため、使った分だけの支払でよいため安価に始められます。

【AWS Black Belt Online Seminar】Amazon CloudFront の概要(YouTube)(52:26)

blackbelt-cloudfront_1

【AWS Black Belt Online Seminar】Amazon CloudFront deep dive(YouTube)(44:42)

blackbelt-cloudfront_2

AmazonCloudFront のこの機能使えてますか(YouTube)(27:31)

blackbelt-cloudfront_3

AWS で実践する CDN セキュリティ(YouTube)(25:58)

blackbelt-cloudfront_4

Amazon CloudFront サービス概要

Amazon CloudFront ドキュメント

Amazon CloudFront よくある質問

Amazon CloudFront 料金

ディストリビューション

ドメイン毎に割り当てられる CloudFront の設定の単位です。デフォルトのドメイン名は「xxxx.cloudfront.net」となっていますが、CNAME エイリアスを利用することで、独自のドメインを割り当てることができます。

オリジン

コンテンツのオリジナルを保持するサーバーのことです。EC2 や S3、オンプレミスのウェブサーバーなどが該当します。

エッジロケーション

世界中に分散して配置されたサーバーでオリジンのデータをキャッシュします。ユーザーを最も近いエッジロケーションに誘導することで、高速に配信することができます。また、オリジンサーバへのアクセスを減らすことが出来るため、負荷軽減になります。

リージョン別エッジキャッシュ

エッジロケーションとオリジンの中間のキャッシュ層です。 エッジロケーションにキャッシュがなければ、オリジンからコンテンツを取得する必要がありますが、ユーザーから遠いリージョンにオリジンがある場合はパフォーマンスの劣化が課題です。 この課題を解決するために導入されたのが、オリジンより近いリージョンの単位でキャッシュし、さらにエッジロケーションより大容量のキャッシュを保持する仕組みです。

ビヘイビア(Behavior)

簡単にいうと、振り分けのルールです。URL のパスパターンでオリジンに振り分けることができます。パスパターンには優先度を付けることができます。 パスパターンには、「api/」や「images/.jpg」のようにファイルパターンまで限定したものも設定できます。 定義したパスパターンごとに以下を設定することが可能です。

キャッシュ無効化(Invalidation)

コンテンツの有効期限が切れる前に、エッジキャッシュからファイルを削除することが出来る機能です。

リリースした際にキャッシュを削除したい場合は手動で実施することができます。

全て消したい場合は、「/*」というパスにすることで一括で削除することができます。

cloudfront-invalidation

複数パスの指定も可能ですが、パスの単位でリクエストが発生することになります。

cloudfront-invalidation-any

1 か月 1000 リクエストまでは無料ですが、それ以上は 0.005USD / リクエストで課金されますので頻繁に実施する場合は、注意が必要です。

圧縮機能

CloudFront エッジでコンテンツを gzip および Brotli 圧縮することで高速にコンテンツを配信することができる機能です。

cloudfront-compress

オリジンサーバが圧縮に対応していない場合でも、手軽に高速化を実現できます。

参考>Brotli(Wikipedia)

価格クラス

CloudFront はデフォルトでは世界中全てのエッジロケーションを利用し、クライアントのロケーションから最もレイテンシーが低いエッジロケーションから配信されます。

cloudfront-priceclass

コスト削減のため一部の地理的リージョンからのレイテンシーの増加を許容できる場合に次に示す料金クラスというものが選択できます。

高コストなエッジロケーションを使用しないようにすることで、コストを抑えることができます。 この料金クラスによって、ユーザーへの配信速度に影響がでる可能性があります。

この中で、日本が含まれるのは「料金クラス ALL」と「料金クラス 200」のみです。 日本リージョンの HTTPS リクエスト(1 万件あたり)の料金は、0.0120 USD です。「料金クラス 100」を選択して北米リージョンに限定した場合の料金は、0.0100 USD となります。

高コストな南米やオーストラリアリージョンからのアクセスを想定しておらず、アクセスがあった場合でもレイテンシーの増加を許容できるならば、「料金クラス 200」を選択しておくとよいでしょう。

署名付き URL と署名付き Cookie を使用したプライベートコンテンツの提供

プライベートコンテンツの配信に利用できる機能です。「ビューワーのアクセスを制限する」を有効にすることで利用できます。 CloudFront に登録したキーペアを利用して生成します。

cloudfront-private-contents

署名付き URL と署名付き Cookie の使い分けは次の通りです。

AWS CLI で署名付き URL を発行する場合は、次のようにします。

aws cloudfront sign \
  --url https://dxxxxxxxxxxxxx.cloudfront.net/example.txt \
  --key-pair-id KXXXXXXXXXXXXX \
  --private-key file://./private_key.pem \
  --date-less-than $((`date "+%s"` + 3600))

有効期限切れの URL にアクセスすると、ステータスコード 403 と下記レスポンスが返却されます。

<?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><Message>Access denied</Message></Error>

Amazon S3 オリジンへのアクセスの制限

S3 をオリジンに設定する場合、オリジンアクセスコントロール (OAC、旧オリジンアクセスアイデンティティ (OAI)) を設定することで、S3 バケットをパブリックアクセス可能にすることなく、意図しない 別の CloudFront ディストリビューション経由のアクセスを制限することができます。

新しい OAC では、OAI で対応していなかった以下に対応できるようになっています。

OAI は引き続き使用することができますが、2022 年 12 月以降に新たに作成されるリージョンでは、OAC のみのサポートとなります。

Amazon CloudFront オリジンアクセスコントロール(OAC)のご紹介-2022/8/31

オリジンアクセスアイデンティティ (OAI) からオリジンアクセスコントロール (OAC) への移行

Application Load Balancers へのアクセスを制限する

CloudFront のオリジンには ALB が設定できます。オリジンに設定するリソースは、パブリック IP によるアクセスができる必要があるため、ALB は インターネット向け(internet-facing)で作成します。

この状態ですと、CloudFront を経由しなくてもアクセスが可能になっています。これでは、CloudFront のメリットを生かすことができません。

ALB を CloudFront 経由のアクセスに限定することで、CloudFront のメリットを生かすことができるようになります。

※ ALB を Internal で構築した場合、オリジンに指定することはできますが、403 エラーとなります。

コンテンツの地理的ディストリビューションの制限

指定した地域からのアクセスをブロックできる機能です。

georestrictions

CloudFront は、サードパーティーのデータベースを使用して、ユーザーがいる場所を判別しており、IP アドレスと国のマッピングはリージョンによって異なるものの、正確性は 99.8% となっています。

ユーザーの場所が特定できなかったときはコンテンツが配信されます。

CloudFront は、AWS Shield Standard によって追加料金なしで保護されています。

AWS Shield Advanced によってさらに高レベルの保護が可能になります。

ただし、1 年のサブスクリプションで固定月額 3,000 USD と、さらにデータ転送量による課金が発生します。

この固定月額料金は、AWS Organizations を利用している場合は組織全体で共有され、アカウント単位で支払う必要はありません。ただし、データ転送量分はアカウント単位で支払う必要があります。

AWS WAF を使用してコンテンツへのアクセスの管理

CDN は様々な脅威に晒されています。AWS WAF を利用して、それらのアクセスから保護することができます。

適用できるものは バージニア北部リージョンで作成した Web ACL のみです。

Amazon CloudFront Origin Shield の使用

CloudFront は、クライアントからのリクエストをエッジロケーションで受け、エッジロケーションにキャッシュがない場合、リージョン別エッジキャッシュという中間層に送信します。

リージョン別エッジキャッシュにキャッシュがない場合は、オリジンにリクエストが送信されます。

origin-shield-off

複数のリージョンで配信するサイトの場合、リージョン別エッジキャッシュからオリジンへのリクエストが重複して送信され、オリジンの負荷が上昇する可能性があります。

これを回避するために、リージョン別エッジキャッシュとオリジンの間の追加キャッシュレイヤーとして動作し、オリジンへの負荷を軽減します。

origin-shield-on

デフォルトでは、「使用しない」となっています。使用する場合は追加コストが発生します。

関数を使用してエッジでカスタマイズ

Lambda@Edge 関数をトリガーできる CloudFront イベント

クライアントのロケーションに近い場所でコードを実行することができます。

cloudfront-lambda@edge_1

cloudfront-lambda@edge_2

ただし、以下のような制約が存在するので注意が必要です(2023 年 1 月時点)。詳しくは、Lambda@Edge に対する制限を参照してください。

標準ログ (アクセスログ) の設定および使用

ログは S3 へエクスポートすることができます(標準ログ)。ログはログ発生から 1 時間以内にまたは、最大で 24 時間遅延することがあります。

標準ログは追加料金が発生しませんが、S3 のアクセスと保管料金がかかります。(標準ログの料金

エクスポートされるログファイルは、次の形式で保存されます。

<optional prefix>/<distribution ID>.YYYY-MM-DD-HH.unique-ID.gz

ex.) example-prefix/EMLARXS9EXAMPLE.2019-11-14-20.RT4KCN4SGK9.gz

ログファイルは、2 行のヘッダー(#Version と #Fields)が含まれたタブ区切りです。(標準ログファイル形式) エクスポートされたログは、Amazon Athena を使って分析する方法が簡単です。(Amazon CloudFront ログのクエリ

#Version: 1.0
#Fields: date time x-edge-location sc-bytes c-ip cs-method cs(Host) cs-uri-stem sc-status cs(Referer) cs(User-Agent) cs-uri-query cs(Cookie) x-edge-result-type x-edge-request-id x-host-header cs-protocol cs-bytes time-taken x-forwarded-for ssl-protocol ssl-cipher x-edge-response-result-type cs-protocol-version fle-status fle-encrypted-fields c-port time-to-first-byte x-edge-detailed-result-type sc-content-type sc-content-len sc-range-start sc-range-end
2019-12-04	21:02:31	LAX1	392	192.0.2.100	GET	d111111abcdef8.cloudfront.net	/index.html	200	-	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/78.0.3904.108%20Safari/537.36	-	-	Hit	SOX4xwn4XV6Q4rgb7XiVGOHms_BGlTAC4KyHmureZmBNrjGdRLiNIQ==	d111111abcdef8.cloudfront.net	https	23	0.001	-	TLSv1.2	ECDHE-RSA-AES128-GCM-SHA256	Hit	HTTP/2.0	-	-	11040	0.001	Hit	text/html	78	-	-
2019-12-04	21:02:31	LAX1	392	192.0.2.100	GET	d111111abcdef8.cloudfront.net	/index.html	200	-	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/78.0.3904.108%20Safari/537.36	-	-	Hit	k6WGMNkEzR5BEM_SaF47gjtX9zBDO2m349OY2an0QPEaUum1ZOLrow==	d111111abcdef8.cloudfront.net	https	23	0.000	-	TLSv1.2	ECDHE-RSA-AES128-GCM-SHA256	Hit	HTTP/2.0	-	-	11040	0.000	Hit	text/html	78	-	-
2019-12-04	21:02:31	LAX1	392	192.0.2.100	GET	d111111abcdef8.cloudfront.net	/index.html	200	-	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/78.0.3904.108%20Safari/537.36	-	-	Hit	f37nTMVvnKvV2ZSvEsivup_c2kZ7VXzYdjC-GUQZ5qNs-89BlWazbw==	d111111abcdef8.cloudfront.net	https	23	0.001	-	TLSv1.2	ECDHE-RSA-AES128-GCM-SHA256	Hit	HTTP/2.0	-	-	11040	0.001	Hit	text/html	78	-	-
2019-12-13	22:36:27	SEA19-C1	900	192.0.2.200	GET	d111111abcdef8.cloudfront.net	/favicon.ico	502	http://www.example.com/	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/78.0.3904.108%20Safari/537.36	-	-	Error	1pkpNfBQ39sYMnjjUQjmH2w1wdJnbHYTbag21o_3OfcQgPzdL2RSSQ==	www.example.com	http	675	0.102	-	-	-	Error	HTTP/1.1	-	-	25260	0.102	OriginDnsError	text/html	507	-	-
2019-12-13	22:36:26	SEA19-C1	900	192.0.2.200	GET	d111111abcdef8.cloudfront.net	/	502	-	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/78.0.3904.108%20Safari/537.36	-	-	Error	3AqrZGCnF_g0-5KOvfA7c9XLcf4YGvMFSeFdIetR1N_2y8jSis8Zxg==	www.example.com	http	735	0.107	-	-	-	Error	HTTP/1.1	-	-	3802	0.107	OriginDnsError	text/html	507	-	-
2019-12-13	22:37:02	SEA19-C2	900	192.0.2.200	GET	d111111abcdef8.cloudfront.net	/	502	-	curl/7.55.1	-	-	Error	kBkDzGnceVtWHqSCqBUqtA_cEs2T3tFUBbnBNkB9El_uVRhHgcZfcw==	www.example.com	http	387	0.103	-	-	-	Error	HTTP/1.1	-	-	12644	0.103	OriginDnsError	text/html	507	-	-

リアルタイムログ

標準ログとは別に、リアルタイムログという機能があります。これは、Kinesis Data Streams を利用してログが配信されるようになる機能です。ただし、サポートするのは Kinesis Data Streams までですので、そこからログを取り出す Kiesis Data Firehose のようなコンシューマーが必要です。

Kiesis Data Firehose を使用した場合、インターバルが 60 ~ 900 秒ですので、リアルタイムといっても 最低 60 秒は遅延します。これよりも短い間隔が必要な場合は独自のコンシューマーを構築する必要があります。

※ただし、下記アップデートにより数秒(5 秒以内)で配信が可能になりました。 (Dec 26, 2023)Amazon Kinesis Data Firehose がゼロバッファリングのサポートを開始

Amazon CloudWatch による CloudFront メトリクスのモニタリング

CloudFront はデフォルトで記録されるメトリクスと、追加設定で記録されるメトリクスがあります。 追加メトリクスはメトリクスごとに料金がかかります。

Using CloudFront continuous deployment to safely test CDN configuration changes(2023 年 1 月時点で英語のみ)

現在の設定に影響を与えることなく、新しい設定のディストリビューションの動作確認を Staging で行うことができます。動作確認ができたら、Staging を昇格させて変更を適用します。

cloudfront-cd_1

cloudfront-cd_2

利用する場合は制約などをドキュメントで確認しておく必要があります。

Quotas and other considerations for continuous deployment

cloudfront