AWSのCDNである強力なサービスCloudFrontを色々と使用してみました。そもそものCDNについての概要から、CloudFrontの実践的な知見等も合わせて記録しておきたいと思います。
見出し
CDN用語
CDNとは
CDNとはContent Delivery Networkの略です。いくらインターネットが光回線と言っても、地球規模で見れば物理的に離れている地域からコンテンツが入っているサーバ(オリジン)へのアクセスは遅くなってしまいます。これを改善する為にCDNがあります。各地域からアクセスされても、それぞれの近い場所(エッジ)から配信されるような仕組みです。
また、エッジでキャッシュを効かせる事で、より迅速なデリバリーを実現する強力なサービスです。速度改善したいという場合には、大きな効果が見込めるはずです。
エッジとは
世界各地に配置されているCDNをする為の配信サーバ群の事です。
Lambda@EdgeというのがCloudFrontに導入出来ますが、これはエッジで稼働するLambdaという意味合いです。ユーザに近い場所で稼働出来るというメリットがあります。
オリジンとは
コンテンツが入っているサーバです。CDNがなければ、普通にイメージする通りこのサーバだけで配信します。
TTLとは
Time To Live の略でキャッシュが生きている期間(秒)の設定です。
CloudFrontとは
CloudFrontとは上記CDNをAWSで簡単に実現する為のサービスです。各地にサーバをデプロイしなくて済みます。
AWS以外でもCDNサービスはありますが、AWSを使用していれば他のAWSサービスと連携して使用出来るメリットがあります。
特に最前段に設置する為、連携要素は多く、WAF、Shield、S3、ELB、Lambda、EC2など幅広く対応されており、重要なサービスとして発展していくと感じております。
連携も多いので設定項目が多く、現状では他のサービスと比較するとハードルが高い方なのかもしれません。
CloudFrontを使用した構成モデル
上で述べたように、CloudFrontは色々なサービスと連携可能です。使用してみた構成モデルを記載しておきます。
CloudFront+Lambda@Edge
自分で関数を実装出来る軽量サーバレスLambdaもなんとこのCloudFrontに直接連携出来ます。どうやって連携するかというと、4種類ありましてAWSの下図を見てください。

- CloudFront がビューワーからリクエストを受信したとき (ビューワーリクエスト)
- CloudFront がリクエストをオリジンに転送する前 (オリジンリクエスト)
- CloudFront がオリジンからレスポンスを受信したとき (オリジンレスポンス)
- CloudFront がビューワーにレスポンスを返す前 (ビューワーレスポンス)
図のように、User>CloudFront>Originという構成のそれぞれのつなぎ目に入れる事が可能です。
具体的な用途としては、httpヘッダーを編集(AWSはhttpヘッダーが付与されるので隠蔽したい場合など)したり、A/Bテストの分岐条件を入れたり出来ます。
CDN周りでちょっとした修正をしたい時に便利かと思います。
ちなみに、viewer の2箇所での Lambda@Edge はメモリ上限が128MBとなっているので、重い処理を入れる事は出来ません。
CloudFrontの注意点
CloudFrontはグローバルな為、ACMをつける場合はメインリージョンのvirginia(us-east-1)にACMを作成する必要があります。
CloudFrontでは1つのACMしか選択できない為、複数ドメインのhttps対応が必要な場合、あらかじめACMをSNIにより複数ドメイン分のACMとして作成しておく必要があります。
初期構築時にDeployされるまでがとにかく長いです。「In Progress」のまま「Deployed」になるのをひたすら待ちます。15分〜60分くらいかかりました。60分かかった時は待てずにガチャガチャやった為、スムーズに行けば平均15〜20分くらいだと思います。長い理由は世界中にあるエッジのキャッシュの為で、CDNなので1リージョンにあるわけではないからです。ただ、順番に設定していっているようなので、更新時のダウンタイムはありません。AWSマネージドサービスの強みですね。
最初は全部キャッシュなしで試してみないと、何がうまく行っているかわからなくなる事がありました。TTLを短めにしてやってみると良いかもしれません。
「Invalidations」 でキャッシュが削除できますが、これもまあまあ長い(数分覚悟)。
キャッシュの期限をどこで設定するか悩みますが、CloudFrontのTTLでmin,max同じ値にして設定して、デプロイ時にキャッシュクリア(Invalidations)するのが良いのかなと思っております。下手にhttpヘッダーにCache-Controlを付加することにより、ブラウザの挙動に任せると意図しないことになりそうなので。
Query String Forwarding and Caching
CloudFrontの設定項目なのですが、パッと見この設定が良くわかりませんでした。選択肢は以下の3種類です。
- None(Improves caching)
- Forward all, chache based on whitelist
- Forward all, cache based on all
このれは、URLパラメータが違うリクエストの場合、前のキャッシュを使いますか?という条件になります。
それぞれ解説します。
None
URLパラメータがついててもついていなくても、異なっていても、パラメータは無視され、全部最初にキャッシュされたもの (パラメータなしURL) で流用されます。URLパラメータなんか使ってないので、付与されても無視で良いよというページの場合、Noneにした方がキャッシュ効率があがります。
Forward all, chache based on whitelist
whitelistに入れたパラメータだけを区別します。他は同じでも異なっていてもキャッシュされます。(whitelistに入れたパラメータだけ付与のURL)
Noneの次に効率が良いです。ただし、パラメータの順番が合っていないといけないので、ちょっと使いづらいような気がします。
Forward all, cache based on all
URLパラメータが1つでも違えば、違うリクエストとして判定して同じキャッシュは使わないようにします。URLパラメータを使う場合はこの設定が良さそうです。キャッシュキーはパラメータ全部含めてです。
CloudFrontのTerraform対応
CloudFrontは現時点(2019/9)でwebコンソールは日本語対応していませんが、Terraformは対応しております。
リソースは以下に対応しており、distributionはCloudFrontの基盤で、origin access identityはS3のポリシー設定時に使用し、public key は謎です(笑)。pemとあるので、たぶんACMを使わない場合のキーだと思われます。
aws_cloudfront_distribution
aws_cloudfront_origin_access_identity
aws_cloudfront_public_key
https://www.terraform.io/docs/providers/aws/r/cloudfront_distribution.html
CloudFront関連エラー等の対応記録等
CloudFrontを使っている中で出て来た問題やエラー対応の記録です。
同じところではまるかもしれないので、タイトルだけでもチラ見推奨です。