AWS学びなおし(+TF)_CloudFront
AWS CloudFront は、コンテンツ配信ネットワーク (CDN) サービスです。世界中に配置されたエッジロケーションと呼ばれるキャッシュサーバーを利用して、ユーザーにコンテンツを高速かつ安全に配信します。ウェブサイト、アプリケーション、動画、API など、様々な種類のコンテンツ配信に利用できます。
CloudFront の主要な概念
-
ディストリビューション (Distribution): CloudFront の設定単位です。ウェブコンテンツを配信するための設定をまとめたもので、オリジン、キャッシュ動作、セキュリティ設定などを定義します。ディストリビューションを作成することで、CloudFront を利用したコンテンツ配信が開始されます。
-
オリジン (Origin): コンテンツのオリジナルデータが保存されている場所です。CloudFront はオリジンからコンテンツを取得し、エッジロケーションにキャッシュします。オリジンには、以下の種類があります。
- S3 バケット (S3 bucket): AWS のストレージサービスである S3 に保存されたコンテンツをオリジンとして利用できます。静的ウェブサイトやファイル配信によく利用されます。
- EC2 インスタンス、Elastic Load Balancing (ELB)、Application Load Balancer (ALB): AWS の仮想サーバーやロードバランサーをオリジンとして利用できます。動的なウェブアプリケーションや API の配信に利用されます。
- カスタムオリジン (Custom Origin): AWS 以外の外部サーバー (オンプレミス環境や他のクラウドプロバイダーのサーバー) をオリジンとして利用できます。
-
エッジロケーション (Edge Location): 世界中に分散配置された CloudFront のキャッシュサーバーです。ユーザーからのリクエストに最も近いエッジロケーションがコンテンツをキャッシュして配信することで、レイテンシを低減し、高速な配信を実現します。
-
キャッシュ (Cache): エッジロケーションにコンテンツを一時的に保存することです。ユーザーからのリクエストに対して、キャッシュされたコンテンツを配信することで、オリジンサーバーへの負荷を軽減し、高速なレスポンスを提供します。
-
キャッシュビヘイビア (Cache Behavior): パスパターンに基づいて、キャッシュの動作を定義する設定です。パスパターンごとに、キャッシュ期間 (TTL)、キャッシュポリシー、オリジンリクエストポリシー、レスポンスヘッダーポリシーなどを個別に設定できます。
-
キャッシュキー (Cache Key): キャッシュを識別するためのキーです。リクエストヘッダー、クエリ文字列、Cookie などをキャッシュキーに含めるかどうかを制御できます。キャッシュキーを適切に設定することで、キャッシュヒット率を向上させ、効率的な配信を実現できます。
-
キャッシュポリシー (Cache Policy): キャッシュキー、キャッシュ期間 (TTL)、マネージドキャッシュポリシーなどを定義する設定です。キャッシュの動作を細かく制御できます。
-
オリジンリクエストポリシー (Origin Request Policy): CloudFront がオリジンにリクエストを送信する際に、どのリクエストヘッダー、クエリ文字列、Cookie をオリジンに転送するかを制御する設定です。
-
レスポンスヘッダーポリシー (Response Headers Policy): CloudFront がユーザーにレスポンスを返す際に、レスポンスヘッダーを追加、変更、削除する設定です。セキュリティヘッダー (例:
Strict-Transport-Security
,X-Frame-Options
) の設定や、キャッシュ制御ヘッダー (Cache-Control
) の調整などに利用できます。 -
CloudFront Functions: 軽量なサーバーレス関数を CloudFront エッジロケーションで実行できる機能です。HTTP リクエスト/レスポンスのヘッダーや URI の書き換え、リダイレクト処理、認証処理など、シンプルな処理を高速に実行できます。
-
Lambda@Edge: AWS Lambda 関数を CloudFront エッジロケーションで実行できる機能です。CloudFront Functions よりも複雑な処理を実行できます。リクエスト/レスポンスのフルボディへのアクセス、より長い実行時間、より多くのメモリなどが利用可能です。
-
Origin Access Control (OAC) / Origin Access Identity (OAI): S3 バケットをオリジンとする場合に、CloudFront 経由でのみ S3 バケットへのアクセスを許可する仕組みです。OAC は OAI の後継となる新しい推奨方式で、よりきめ細かいアクセス制御が可能です。
-
ジオロケーション制限 (Geo Restriction): 特定の国からのアクセスを許可または拒否する機能です。コンテンツの配信対象地域を制限したい場合に利用できます。
-
AWS WAF 連携: AWS WAF (Web Application Firewall) と連携することで、悪意のあるリクエストからウェブアプリケーションを保護できます。SQL インジェクション、クロスサイトスクリプティング (XSS) などの一般的なウェブ攻撃から防御できます。
-
AWS Shield 連携: AWS Shield と連携することで、DDoS (分散型サービス拒否) 攻撃からウェブアプリケーションを保護できます。Standard と Advanced のプランがあり、Advanced プランではより高度なDDoS防御機能を利用できます。
CloudFront の基本的な流れ
- ユーザーがコンテンツをリクエスト: ユーザーがウェブブラウザやアプリケーションからコンテンツ (例: ウェブページ、画像、動画) をリクエストします。
-
DNS 名前解決: ユーザーのリクエストは、CloudFront ディストリビューションに関連付けられたドメイン名 (例:
d1234abcd.cloudfront.net
やカスタムドメイン名) に解決されます。 - エッジロケーションへのルーティング: DNS 解決の結果、リクエストはユーザーに最も近い CloudFront エッジロケーションにルーティングされます。
- キャッシュの確認: エッジロケーションは、リクエストされたコンテンツがキャッシュに存在するかどうかを確認します。
- キャッシュヒット (Cache Hit): コンテンツがキャッシュに存在する場合、エッジロケーションはキャッシュされたコンテンツをユーザーに直接配信します。高速なレスポンスが実現されます。
- キャッシュミス (Cache Miss): コンテンツがキャッシュに存在しない場合、エッジロケーションはオリジン (S3 バケット、EC2 インスタンスなど) にリクエストを転送し、コンテンツを取得します。
- オリジンからのコンテンツ取得: オリジンはリクエストされたコンテンツをエッジロケーションに返します。
- キャッシュと配信: エッジロケーションは、オリジンから取得したコンテンツをキャッシュに保存し、ユーザーに配信します。次回以降のリクエストに備えてキャッシュを行います。
CloudFront の重要性
CloudFront は、ウェブコンテンツ配信のパフォーマンス、セキュリティ、可用性を向上させるために不可欠なサービスです。
- パフォーマンス向上: エッジロケーションでのキャッシュにより、ユーザーはオリジンサーバーから遠く離れていても、高速にコンテンツを取得できます。レイテンシが低減し、ウェブサイトやアプリケーションの応答性が向上します。
- オリジンサーバーの負荷軽減: キャッシュヒット率が高いほど、オリジンサーバーへのリクエストが減少し、負荷を大幅に軽減できます。オリジンサーバーの処理能力を効率的に利用できます。
- 可用性向上: 世界中に分散されたエッジロケーションを利用することで、オリジンサーバーに障害が発生した場合でも、キャッシュされたコンテンツを配信し続けることができ、可用性を向上させることができます。
- セキュリティ強化: HTTPS による暗号化通信、AWS WAF や AWS Shield との連携によるウェブアプリケーション保護、ジオロケーション制限によるアクセス制御など、様々なセキュリティ機能を提供し、安全なコンテンツ配信を実現します。
- コスト削減: オリジンサーバーのデータ転送料金を削減できます。特に S3 バケットをオリジンとする場合、CloudFront 経由でのデータ転送料金は S3 から直接配信する場合よりも安価になる場合があります。
【実務レベルの内容と重要事項】
実務レベルで CloudFront を扱う上で重要な事項は多岐に渡りますが、特に以下の点が重要です。
1. キャッシュ戦略の設計:
- 適切なキャッシュ期間 (TTL) の設定: コンテンツの更新頻度に合わせて適切な TTL を設定します。頻繁に更新されるコンテンツは短い TTL、静的なコンテンツは長い TTL を設定します。
- キャッシュキーの最適化: キャッシュヒット率を最大化するために、キャッシュキーに含める要素 (リクエストヘッダー、クエリ文字列、Cookie) を適切に選択します。不要な要素をキャッシュキーに含めると、キャッシュヒット率が低下する可能性があります。
- キャッシュ無効化 (Invalidation): コンテンツを更新した場合、CloudFront のキャッシュを無効化する必要があります。パスベースの無効化や、オリジンヘッダーに基づいた自動無効化などを検討します。
2. オリジンの適切な選択と設定:
- オリジンの種類: コンテンツの種類や配信要件に応じて、S3 バケット、EC2 インスタンス、ALB、カスタムオリジンなど、最適なオリジンを選択します。
- オリジンへのアクセス制御 (OAC/OAI): S3 バケットをオリジンとする場合は、OAC または OAI を設定し、CloudFront 経由でのみ S3 バケットへのアクセスを許可するように設定します。
- オリジングループ: 複数のオリジンをグループ化し、プライマリオリジンに障害が発生した場合に、セカンダリオリジンに自動的にフェイルオーバーするオリジングループの利用を検討します。可用性を向上させることができます。
-
オリジンパス: ディストリビューションのルートパス(
/
) とオリジンのルートパスが異なる場合に、オリジンパスを設定することで、CloudFront がオリジン内の正しいパスからコンテンツを取得できるようにします。
3. セキュリティ対策:
- HTTPS の強制: ビューワープロトコルポリシーを "Redirect HTTP to HTTPS" または "HTTPS Only" に設定し、HTTPS でのアクセスを強制します。
- TLS 証明書: HTTPS を有効にするには、TLS 証明書が必要です。AWS Certificate Manager (ACM) で証明書を発行し、CloudFront ディストリビューションに関連付けます。
- AWS WAF 連携: AWS WAF と連携し、ウェブアプリケーションファイアウォールルールを設定することで、悪意のあるリクエストからウェブアプリケーションを保護します。
- ジオロケーション制限: 必要に応じてジオロケーション制限を設定し、特定の国からのアクセスを制限します。
- 署名付き URL / Cookie: 認証されたユーザーのみにコンテンツを配信したい場合は、署名付き URL または署名付き Cookie を利用します。
4. パフォーマンスチューニング:
- 圧縮 (Gzip / Brotli): コンテンツを圧縮して配信することで、データ転送量を削減し、パフォーマンスを向上させることができます。CloudFront コンソールまたは Terraform で圧縮設定を有効にします。
- HTTP/2, HTTP/3 の有効化: 最新の HTTP プロトコルを有効にすることで、パフォーマンスを向上させることができます。CloudFront ではデフォルトで HTTP/2 が有効になっています。HTTP/3 はディストリビューションの設定で有効にできます。
- Connection Keep-Alive: オリジンとの永続的な接続 (Keep-Alive) を有効にすることで、接続確立のオーバーヘッドを削減し、パフォーマンスを向上させることができます。
5. 監視とログ:
- CloudWatch メトリクス: CloudFront のパフォーマンスやエラー率などのメトリクスを CloudWatch で監視します。
- CloudWatch Logs: CloudFront Functions や Lambda@Edge のログを CloudWatch Logs に出力し、エラーや問題を分析します。
- アクセスログ (Standard Logging): CloudFront へのアクセスログを S3 バケットに出力し、アクセス状況の分析、セキュリティ監査、トラブルシューティングなどに活用します。
6. エラー処理:
- カスタムエラーページ: HTTP エラーコード (例: 404 Not Found, 503 Service Unavailable) ごとにカスタムエラーページを設定し、ユーザーエクスペリエンスを向上させます。
7. 関数 (CloudFront Functions, Lambda@Edge) の活用:
- リクエスト/レスポンスのカスタマイズ: CloudFront Functions や Lambda@Edge を利用して、リクエストヘッダー、URI、レスポンスヘッダーなどを書き換え、コンテンツ配信を柔軟にカスタマイズします。
- 認証処理: Lambda@Edge を利用して、エッジロケーションで認証処理を実行し、認証されたユーザーのみにコンテンツを配信できます。
- A/B テスト、パーソナライズ: Lambda@Edge を利用して、ユーザー属性に基づいてコンテンツを動的に変更し、A/B テストやパーソナライズされたコンテンツ配信を実現できます。
8. コスト最適化:
- キャッシュヒット率の向上: キャッシュ戦略を最適化し、キャッシュヒット率を向上させることで、オリジンへのリクエストを減らし、データ転送料金を削減できます。
- 不要な機能の無効化: 使用していない機能 (例: アクセスログ) は無効化し、コストを削減します。
- リザーブドインスタンス (Lambda@Edge): Lambda@Edge を頻繁に利用する場合は、リザーブドインスタンスの利用を検討し、コストを削減します。
9. Terraform による IaC (Infrastructure as Code) の実践:
- CloudFront ディストリビューションの設定を Terraform コードで管理することで、設定のバージョン管理、再現性、自動化を実現します。
- モジュール化、変数、データソースなどを活用し、Terraform コードの保守性、再利用性を高めます。
【実務でどの程度使用されるのか】
CloudFront は、実務において非常に頻繁に使用される AWS サービスの一つです。ウェブサイトやアプリケーションを公開するほぼ全てのケースで、CloudFront の利用が検討されると言っても過言ではありません。
実務での CloudFront 利用例:
- ウェブサイト/ウェブアプリケーションの高速化: ウェブサイトやウェブアプリケーションの静的コンテンツ (HTML, CSS, JavaScript, 画像, 動画など) を CloudFront で配信することで、パフォーマンスを大幅に向上させます。ユーザーエクスペリエンスの向上、SEO 対策、コンバージョン率向上などに貢献します。
- 動画配信プラットフォーム: 動画コンテンツを CloudFront で配信することで、世界中のユーザーに高品質な動画を安定的に配信できます。VOD (ビデオオンデマンド) やライブストリーミング配信に利用されます。
- ソフトウェア/ファイルダウンロード: ソフトウェア、ドキュメント、アーカイブファイルなどを CloudFront で配信することで、ダウンロード速度を向上させ、ユーザーへの迅速なファイル提供を実現します。
- API Gateway との連携: API Gateway で構築した API のエンドポイントを CloudFront で配信することで、API の応答速度を向上させ、負荷分散、セキュリティ強化を実現します。
- 静的ウェブサイトホスティング (S3 + CloudFront): S3 バケットに静的ウェブサイトをホスティングし、CloudFront で配信する構成は、コスト効率が高く、スケーラビリティに優れています。
- グローバル展開: 世界中にエッジロケーションを持つ CloudFront を利用することで、グローバルに展開するウェブサイトやアプリケーションでも、世界中のユーザーに高速なコンテンツ配信を実現できます。
- 大規模イベント/トラフィック急増への対策: CloudFront は高いスケーラビリティを持つため、大規模イベントやトラフィック急増時にも安定した配信を維持できます。
CloudFront はDevSecOpsにおける重要な要素:
CloudFront は、DevSecOps の文脈においても重要な役割を果たします。パフォーマンス向上、セキュリティ強化、可用性向上に貢献し、開発、セキュリティ、運用チーム間の連携を促進します。IaC (Infrastructure as Code) を活用した CloudFront の自動構築・デプロイ、CI/CD パイプラインへの組み込み、セキュリティ設定のコード化など、DevSecOps プラクティスを実践する上で CloudFront は不可欠な要素となります。
CloudFront のスキルは市場価値が高い:
クラウドエンジニア、インフラエンジニア、DevOps エンジニア、バックエンドエンジニアなど、ウェブアプリケーション開発やインフラ構築に関わる職種において、CloudFront の知識・スキルは非常に重要であり、市場価値も高いです。CloudFront を深く理解し、適切に設計・運用できる人材は、企業にとって非常に貴重な存在です。
【terraformのコードで記述する場合の基本的内容と実務レベルの内容】
Terraform で CloudFront ディストリビューションを記述する場合、主に aws_cloudfront_distribution
リソースを使用します。
Terraform での CloudFront 記述の基本:
resource "aws_cloudfront_distribution" "example" {
origin {
domain_name = aws_s3_bucket.example.bucket_regional_domain_name
origin_id = "S3Origin"
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path
}
}
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3Origin"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
resource "aws_s3_bucket" "example" {
bucket = "example-bucket-name"
}
resource "aws_cloudfront_origin_access_identity" "example" {
comment = "OAI for example bucket"
}
上記のコードは、基本的な CloudFront ディストリビューションの設定例です。S3 バケットをオリジンとし、OAI (Origin Access Identity) を利用して S3 バケットへのアクセスを CloudFront 経由のみに制限しています。
Terraform での CloudFront 記述の実務レベルの内容:
実務レベルで Terraform を用いて CloudFront を管理する場合、以下の点を考慮する必要があります。
- 変数 (Variables) の活用:
- 環境 (開発環境、本番環境など) やプロジェクトによって異なる値を Terraform 変数として定義し、コードの再利用性を高めます。
- S3 バケット名、ドメイン名、キャッシュ期間、ジオロケーション制限などを変数化します。
- モジュール (Modules) の活用:
- CloudFront ディストリビューションの設定をモジュール化し、コードの構造化と再利用性を高めます。
- 例えば、静的ウェブサイト配信用の CloudFront モジュール、API Gateway 連携用の CloudFront モジュールなどを作成します。
- データソース (Data Sources) の活用:
- 既存の AWS リソースの情報 (例: ACM 証明書の ARN, WAF WebACL の ARN, Route 53 ホストゾーン ID) をデータソースから取得し、コード内で動的に利用します。
- キャッシュポリシー、オリジンリクエストポリシー、レスポンスヘッダーポリシーの定義:
-
cache_policy_id
,origin_request_policy_id
,response_headers_policy_id
引数を利用して、aws_cloudfront_cache_policy
,aws_cloudfront_origin_request_policy
,aws_cloudfront_response_headers_policy
リソースで定義したポリシーをキャッシュビヘイビアに関連付けます。
resource "aws_cloudfront_cache_policy" "example_cache_policy" {
name = "example-cache-policy"
default_ttl = 3600
min_ttl = 0
max_ttl = 86400
query_string_config {
query_string_behavior = "whitelist"
query_strings = ["param1", "param2"]
}
# ...
}
resource "aws_cloudfront_distribution" "example" {
# ...
default_cache_behavior {
# ...
cache_policy_id = aws_cloudfront_cache_policy.example_cache_policy.id
}
# ...
}
- CloudFront Functions, Lambda@Edge の設定:
-
function_association
ブロックまたはlambda_function_association
ブロックを利用して、CloudFront Functions または Lambda@Edge 関数をキャッシュビヘイビアに関連付けます。
resource "aws_cloudfront_function" "example_function" {
name = "example-function"
runtime = "cloudfront-js-1.0"
code = file("function.js") # 関数コードのファイルパス
}
resource "aws_cloudfront_distribution" "example" {
# ...
default_cache_behavior {
# ...
function_association {
event_type = "viewer-request"
function_arn = aws_cloudfront_function.example_function.arn
}
}
# ...
}
- Origin Access Control (OAC) の設定:
-
origin_access_control_id
引数を利用して、aws_cloudfront_origin_access_control
リソースで定義した OAC をオリジンに関連付けます。OAC を利用する場合は、s3_origin_config
ブロックのorigin_access_identity
引数は不要になります。
resource "aws_cloudfront_origin_access_control" "example_oac" {
name = "example-oac"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
resource "aws_cloudfront_distribution" "example" {
origin {
domain_name = aws_s3_bucket.example.bucket_regional_domain_name
origin_id = "S3Origin"
s3_origin_config {
origin_access_control_id = aws_cloudfront_origin_access_control.example_oac.id
}
}
# ...
}
- AWS WAF WebACL 連携:
-
web_acl_id
引数を利用して、AWS WAF WebACL をディストリビューションに関連付けます。
data "aws_wafv2_web_acl" "example_webacl" {
name = "example-webacl"
scope = "CLOUDFRONT"
}
resource "aws_cloudfront_distribution" "example" {
# ...
web_acl_id = data.aws_wafv2_web_acl.example_webacl.arn
# ...
}
- カスタムエラーレスポンスの設定:
-
custom_error_response
ブロックを利用して、カスタムエラーレスポンスを設定します。
resource "aws_cloudfront_distribution" "example" {
# ...
custom_error_response {
error_code = 404
response_code = 404
response_page_path = "/error.html"
minimum_protocol_version = "TLSv1.2"
}
# ...
}
- ログ設定:
-
logging_config
ブロックを利用して、アクセスログの出力設定を行います。
resource "aws_cloudfront_distribution" "example" {
# ...
logging_config {
enabled = true
include_cookies = false
bucket = aws_s3_bucket.log_bucket.bucket_regional_domain_name
prefix = "cloudfront-logs/"
}
# ...
}
resource "aws_s3_bucket" "log_bucket" {
bucket = "example-log-bucket-name"
}
- CDN 証明書 (ACM) の設定:
-
viewer_certificate
ブロックで、ACM で発行した証明書 (acm_certificate_arn
) または IAM にアップロードした証明書 (iam_certificate_id
) を指定します。カスタムドメイン名を使用する場合は必須です。
data "aws_acm_certificate" "example_cert" {
domain = "example.com"
statuses = ["ISSUED"]
}
resource "aws_cloudfront_distribution" "example" {
# ...
viewer_certificate {
acm_certificate_arn = data.aws_acm_certificate.example_cert.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
}
# ...
}
- Terraform Cloud/Enterprise の活用:
- チームでの Terraform 運用を行う場合、Terraform Cloud や Terraform Enterprise を活用することで、状態管理、コラボレーション、ガバナンスなどを強化できます。
Terraform を活用することで、CloudFront ディストリビューションの設定をコードとして管理し、効率的かつ安全なインフラ構築・運用を実現できます。上記の基本と実務レベルの内容を理解し、Terraform を効果的に活用してください。
Discussion