CloudFront ON Terraform
業務でCloudFrontを構築したので振り返りとCDN学習の為に備忘録を残しておきます。
アジェンダ
1, cloudfrontとは
2, CDNとは
3, CDN概要
4, cloudfrontの用語集
5, terraformで表現する
CloudFrontとは?
cloud frontはエッジサービスとして位置付けされており、グローバルサービスである。AWSのリージョン外のサービスであることを忘れずに!
そしてリージョン外なのでuserに近いサービスと言える。各地にエッジロケーションが存在する。
なのでuserに一番近いエッジロケーションからコンテンツが配信される為、低レイテンシーなサービスを提供できる。
もっと深ぼって行くと、cloudfrontはCDN(コンテンツデリバリーネットワーク)である。
CDNとは?
CDNとは「Content Delivery Network(コンテンツデリバリーネットワーク)」の略で、ウェブコンテンツを効率的かつスピーディーに配信できるように工夫されたネットワークのことです。
用途としてはオリジンサーバー(APサーバー)の負荷軽減として用いられます。userとオリジンサーバーの間にCDNを配置しオリジンからレスポンスされてコンテンツをキャッシュしておきます。
キャッシュすることで、2回目に同じリクエスがあり、コンテンツをレスポンスする際にキャッシュされたコンテンツをレスポンスします。それによって、オリジンサーバーの負荷は軽減されて、なおかつresponse timeが向上しレイテンシーの改善につながります。
AWSではこのCDNサービスを提供しているのがcloudfrontになります。
※aws参考資料から抜粋※
CloudFrontの用語集
ビューワー(Viewer)
クライアント・webブラウザー
ディストリビューション(Distribution)
コンテンツ配信の設定単位
オリジン(origein)
コンテンツ提供元のサーバー、laravelの構成だとプロキシとして据えているnginx、はたまたS3をオリジンに据えたりと柔軟に対応ができる。
ビフェイビア(behavior)
キャッシュ動作設定、URLパスパターン毎に設定。
上記がキーとなるワードだ
一つ一つ構成要素をterraformのコードと一緒に見ていこう!
ディストリビューション
コンテンツ配信の構成設定を行う。オリジンの設定やら、ビフェイビアの設定やら。ちなみにオリジンの登録25個まで登録が可能。
下記のterraformのコードを見るかぎりdistributionの中にoriginやviewerやbehaviorの設定を記述していく
resource "aws_cloudfront_distribution" "assets" {
enabled = true
is_ipv6_enabled = true
comment = "For ${var.project} Asset files(${var.env})"
aliases = ["${var.sub_domain}${var.domain}"]
viewer_certificate {
cloudfront_default_certificate = false
acm_certificate_arn = aws_acm_certificate.cdn.arn
minimum_protocol_version = "TLSv1.2_2019"
ssl_support_method = "sni-only"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
origin {
domain_name = aws_lb.web.dns_name
origin_id = "${var.env}-${var.project}-web-alb"
custom_origin_config {
http_port = 80
https_port = 443
origin_keepalive_timeout = 5
origin_protocol_policy = "https-only"
origin_read_timeout = 60
origin_ssl_protocols = [
"TLSv1.2",
]
}
}
origin {
domain_name = aws_s3_bucket.assets.bucket_regional_domain_name
origin_id = "S3-${aws_s3_bucket.assets.bucket}"
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.asset_origin_access_identity.cloudfront_access_identity_path
}
}
origin {
domain_name = aws_s3_bucket.uploads.bucket_regional_domain_name
origin_id = aws_s3_bucket.uploads.bucket
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.web_uploads.cloudfront_access_identity_path
}
}
ordered_cache_behavior {
path_pattern = "/public/*"
allowed_methods = [
"GET",
"HEAD",
]
cached_methods = [
"GET",
"HEAD",
]
target_origin_id = "S3-${aws_s3_bucket.assets.bucket}"
compress = true
default_ttl = 86400
max_ttl = 259200
min_ttl = 0
smooth_streaming = false
trusted_signers = []
viewer_protocol_policy = "redirect-to-https"
forwarded_values {
headers = [
"Accept",
"Origin",
]
query_string = false
query_string_cache_keys = []
cookies {
forward = "none"
whitelisted_names = []
}
}
}
ordered_cache_behavior {
path_pattern = "/uploads/*"
allowed_methods = [
"GET",
"HEAD",
]
cached_methods = [
"GET",
"HEAD",
]
compress = false
default_ttl = 86400
max_ttl = 259200
min_ttl = 0
smooth_streaming = false
target_origin_id = aws_s3_bucket.uploads.bucket
trusted_signers = []
viewer_protocol_policy = "redirect-to-https"
forwarded_values {
headers = [
"Accept",
"Origin",
]
query_string = false
query_string_cache_keys = []
cookies {
forward = "none"
whitelisted_names = []
}
}
}
default_cache_behavior {
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 0
max_ttl = 0
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cached_methods = ["GET", "HEAD"]
compress = false
target_origin_id = "${var.env}-${var.project}-web-alb"
forwarded_values {
query_string = true
headers = ["*"]
cookies {
forward = "all"
}
}
}
}
構成要素の一つずつ見ていく
> aliasesがすでに作成されたAレコード。
こいつとcloudforntのDNS名が紐付いたCNAMEレコードを作成される。
> 事前準備としてroute53でAレコード、AAAレコード作成が必要。
enabled = true
is_ipv6_enabled = true -> IPv6も有効にしておくとIPv6のリクエストも受け付ける。
route53で作成が必要
comment = "For ${var.project} Asset files(${var.env})"
aliases = ["${var.sub_domain}${var.domain}"]
viewer_certificateのTLS設定を行う。
SNIとは「Server Name Indication」の略で、SSL/TLSの拡張仕様の1つです。通常SSL証明書の設置には1つの証明書に対して1つの専用IPアドレスが必要となりますが、SNIを利用すると、1つのIPアドレスで複数のSSL証明書が設置可能となるため、専用IPアドレスが不要となります。
→前提としてcloudfrontのドメイン名とELBで使用するドメイン名は一緒であるのでsni-only設定が必要?(今後学習して修正します)
viewer_certificate {
cloudfront_default_certificate = false
acm_certificate_arn = aws_acm_certificate.cdn.arn
minimum_protocol_version = "TLSv1.2_2019" ->どのTLSを有効かするか。ここは有無を言わず、
最新のものを選択使用
ssl_support_method = "sni-only"
}
> restrictions(地域制限)
特定の国のユーザーによるコンテンツへのアクセスを回避する必要がある場合は、CloudFront の地域制限を使用して設定ができる
restrictions {
geo_restriction {
restriction_type = "none" → 今回は制限なし
}
}
origin
origin今回オリジンの設定は ELB×1 s3×2 の3つ設定している。
・dns_nameで当該のリソースを指定する。
・ custom_origin_configでオリジンの構成設定をする。
・s3の場合はs3_origin_configで定義
・s3をホストするにはオリジンアクセスアイデンティティ (OAI)が必要にな
ります。s3アクセスするのはcloudfrontのURLのみ許可する場合はOAIを定
義してそいつをoriginで紐付けます。このOAIを紐付けたら、
S3のインラインポリシーでprincipalsでOAIを定義しときます。これで安全
にアクセスが可能となります。
・ Origin Shieldという機能もあるけど、今後調べて修正します。
origin {
domain_name = aws_lb.web.dns_name
origin_id = "${var.env}-${var.project}-web-alb"
custom_origin_config {
http_port = 80
https_port = 443
origin_keepalive_timeout = 5
origin_protocol_policy = "https-only" -> https_onlyのにしとくべし。
ALBではリスナーではHttpsしか受け付けないように設定しとけば良い
origin_read_timeout = 60
origin_ssl_protocols = [
"TLSv1.2", -> TLSのバージョンは最新にね。
]
}
}
origin {
domain_name = aws_s3_bucket.assets.bucket_regional_domain_name
origin_id = "S3-${aws_s3_bucket.assets.bucket}"
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.asset_origin_access_identity.cloudfront_access_identity_path
}
}
origin {
domain_name = aws_s3_bucket.uploads.bucket_regional_domain_name
origin_id = aws_s3_bucket.uploads.bucket
s3_origin_config {
OAIの指定
origin_access_identity = aws_cloudfront_origin_access_identity.web_uploads.cloudfront_access_identity_path
}
}
########
OAI
resource "aws_cloudfront_origin_access_identity" "asset_origin_access_identity" {
comment = "${var.project} origin access identity for asset files"
}
resource "aws_cloudfront_origin_access_identity" "web_uploads" {
comment = "${var.project} origin access identity for upload files"
}
##########
behavior
・behavior
パスパターンやキャッシュ設定、ヘッダの設定をする
ordered_cache_behavior { -> s3のbehaviorの設定。アセット
path_pattern = "/uploads/*"
allowed_methods = [
"GET",
"HEAD",
]
cached_methods = [
"GET",
"HEAD",
]
compress = false
default_ttl = 86400
max_ttl = 259200
min_ttl = 0
smooth_streaming = false
target_origin_id = aws_s3_bucket.uploads.bucket
trusted_signers = []
viewer_protocol_policy = "redirect-to-https"
forwarded_values {
headers = [
"Accept",
"Origin",
]
query_string = false
query_string_cache_keys = []
cookies {
forward = "none"
whitelisted_names = []
}
}
}
default_cache_behavior { -> デフォルトのbehavoir設定。パスパターンはariaceで定義されたもの/以下にはず。
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 0
max_ttl = 0
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cached_methods = ["GET", "HEAD"]
compress = false
target_origin_id = "${var.env}-${var.project}-web-alb" -> albをターゲットに
forwarded_values {
query_string = true
headers = ["*"]
cookies {
forward = "all"
}
}
allowed_methodst
HTTP メソッドを処理するよう CloudFront を構成すると、CloudFront はビューワーからの以下のリクエストを受け入れてカスタムオリジンに転送します。
DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
今回はdefault_cache_behaviorで設定されているoriginサーバーはELBとなっており、その先に待ち構えているのはhttpサーバーなので上記を設定する.
ただ今回はsame originなのでoption headerとかいる?となるが、その受け入れはhttpサーバーが側で設定するはず!
以上ではありますが、振り返りは以上です。構築したコードを見直すのはいいことですね。webブラウザーセキュリティとかの本を読んだ後に、コードを見直すといろんな気づきがあります。。(勉強不足)
ここにはまだ記述してないですが、cloudfrontからの通信をhttps化にする際にTLSのリクエスト方法が少し変わっているので、今後記事を追記していこうと思います。
それではまた〜
この記事が気に入ったらサポートをしてみませんか?