
Amazon CloudFront 標準ログ v2(アクセスログ)を Amazon S3 に保存する構成を Terraform で実装する機会があった.個人環境で検証したことをまとめておこうと思う❗️
Amazon S3 関連
まずは Amazon CloudFront 標準ログ v2(アクセスログ)を保存する Amazon S3 バケットを作る.バケットポリシーはドキュメントを参考に設定した🔐バケットポリシーに設定している aws_cloudwatch_log_delivery_source.logs.arn は後述する.
resource "aws_s3_bucket" "logs" { bucket = "kakakakakku-sandbox-cdn-logs" } resource "aws_s3_bucket_public_access_block" "logs" { bucket = aws_s3_bucket.logs.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } resource "aws_s3_bucket_policy" "logs" { bucket = aws_s3_bucket.logs.id policy = data.aws_iam_policy_document.logs.json } data "aws_iam_policy_document" "logs" { statement { principals { type = "Service" identifiers = ["delivery.logs.amazonaws.com"] } actions = ["s3:PutObject"] resources = ["${aws_s3_bucket.logs.arn}/*"] condition { test = "StringEquals" variable = "aws:SourceAccount" values = [data.aws_caller_identity.current.account_id] } condition { test = "ArnLike" variable = "aws:SourceArn" values = [aws_cloudwatch_log_delivery_source.logs.arn] } } }
Amazon CloudWatch Logs 関連
今回の実装のポイントは Amazon CloudWatch Logs 関連で,Terraform で Amazon CloudFront 標準ログ v2(アクセスログ)を設定する場合は以下3種類のリソースを使う必要がある.さらに us-east-1 リージョンにデプロイする必要がある🌍️
- aws_cloudwatch_log_delivery
- aws_cloudwatch_log_delivery_source
- aws_cloudwatch_log_delivery_destination
今回は
- Hive フォーマット
- Amazon S3 出力
- Parquet 形式
にした.このあたりは自由に変えてもらって OK👌
resource "aws_cloudwatch_log_delivery" "logs" { region = "us-east-1" delivery_source_name = aws_cloudwatch_log_delivery_source.logs.name delivery_destination_arn = aws_cloudwatch_log_delivery_destination.logs.arn s3_delivery_configuration { suffix_path = "/{yyyy}/{MM}/{dd}/{HH}" enable_hive_compatible_path = true } } resource "aws_cloudwatch_log_delivery_source" "logs" { region = "us-east-1" name = "sandbox-cdn-logs-source" log_type = "ACCESS_LOGS" resource_arn = aws_cloudfront_distribution.main.arn } resource "aws_cloudwatch_log_delivery_destination" "logs" { region = "us-east-1" name = "sandbox-cdn-logs-destination" output_format = "parquet" delivery_destination_configuration { destination_resource_arn = aws_s3_bucket.logs.arn } }
Amazon CloudFront 関連
最後に Amazon CloudFront ディストリビューションとオリジンとして使う Amazon S3 バケットをデプロイする👌今回は適当にカスタムドメインでアクセスできるようにした.
data "aws_route53_zone" "main" { name = "xxx.com" } resource "aws_s3_bucket" "assets" { bucket = "kakakakakku-sandbox-assets" } resource "aws_s3_bucket_public_access_block" "assets" { bucket = aws_s3_bucket.assets.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } resource "aws_s3_bucket_policy" "assets" { bucket = aws_s3_bucket.assets.id policy = data.aws_iam_policy_document.assets.json } data "aws_iam_policy_document" "assets" { statement { principals { type = "Service" identifiers = ["cloudfront.amazonaws.com"] } actions = ["s3:GetObject"] resources = ["${aws_s3_bucket.assets.arn}/*"] condition { test = "StringEquals" variable = "aws:SourceArn" values = [aws_cloudfront_distribution.main.arn] } } } resource "aws_acm_certificate" "cdn" { region = "us-east-1" domain_name = "sandbox-cdn.xxx.com" validation_method = "DNS" lifecycle { create_before_destroy = true } } resource "aws_route53_record" "validation" { for_each = { for dvo in aws_acm_certificate.cdn.domain_validation_options : dvo.domain_name => { name = dvo.resource_record_name record = dvo.resource_record_value type = dvo.resource_record_type } } allow_overwrite = true zone_id = data.aws_route53_zone.main.zone_id name = each.value.name type = each.value.type records = [each.value.record] ttl = 60 } resource "aws_cloudfront_origin_access_control" "main" { name = "sandbox-cdn-oac" origin_access_control_origin_type = "s3" signing_behavior = "always" signing_protocol = "sigv4" } resource "aws_cloudfront_distribution" "main" { enabled = true aliases = ["sandbox-cdn.xxx.com"] origin { domain_name = aws_s3_bucket.assets.bucket_regional_domain_name origin_id = aws_s3_bucket.assets.id origin_access_control_id = aws_cloudfront_origin_access_control.main.id } default_cache_behavior { target_origin_id = aws_s3_bucket.assets.id viewer_protocol_policy = "redirect-to-https" allowed_methods = ["GET", "HEAD"] cached_methods = ["GET", "HEAD"] forwarded_values { query_string = false cookies { forward = "none" } } } restrictions { geo_restriction { restriction_type = "none" } } viewer_certificate { acm_certificate_arn = aws_acm_certificate.cdn.arn ssl_support_method = "sni-only" minimum_protocol_version = "TLSv1.2_2021" } } resource "aws_route53_record" "cdn" { zone_id = data.aws_route53_zone.main.zone_id name = "sandbox-cdn.xxx.com" type = "A" alias { name = aws_cloudfront_distribution.main.domain_name zone_id = aws_cloudfront_distribution.main.hosted_zone_id evaluate_target_health = false } }
デプロイ確認

