以下の内容はhttps://kakakakakku.hatenablog.com/entry/2026/02/05/083323より取得しました。


Amazon CloudFront 標準ログ v2 を Terraform でデプロイする

Amazon CloudFront 標準ログ v2(アクセスログ)を Amazon S3 に保存する構成を Terraform で実装する機会があった.個人環境で検証したことをまとめておこうと思う❗️

docs.aws.amazon.com

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 リージョンにデプロイする必要がある🌍️

今回は

  • 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
  }
}

デプロイ確認

Amazon CloudFront ログ設定

Amazon S3 バケットに出力されたログ

関連記事

kakakakakku.hatenablog.com




以上の内容はhttps://kakakakakku.hatenablog.com/entry/2026/02/05/083323より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14