CloudFront標準ログ記録にレガシーと非レガシーが存在していたので非レガシーにしてみた

はじめに

久しぶりのブログ投稿となります。

Cloudfrontのアクセスログとして標準ログ記録があり、2024年11月20日に標準ログ記録 (v2)をサポートしていたみたいで、標準ログ記録 (レガシー)の表記があったので調べて見て対応したという内容になります。

標準ログ記録 (レガシー)を引き続きCloudFrontで使用し続けることは可能ですが、気持ち的に最新にしてみたいですよね。

ログの記録形式や配信先、パーティショニング等の柔軟性が柔軟になっています。

前提事項

  • Terraform コードでの設定になります。

CloudFront 標準ログ記録 (v2) 設定項目

次のリソースをそれぞれ設定していく必要があります。
それぞれTerraformコードと共に説明していきます。

  • 配信元(Delivery Source)の作成
  • 配信先(Delivery Destination)の作成
  • 配信(Delivery)の作成
  • S3 バケットポリシー設定

配信元(Delivery Source)の作成

CloudFrontからの配信ですので log_type には、「ACCESS_LOGS」を指定します。

リソース arn には、CloudFrontのディストリビューション arn を指定します。

resource "aws_cloudwatch_log_delivery_source" "cloudfront_access_logs" {
  provider = aws.us_east_1

  name         = "delivery_source-example-name"
  log_type     = "ACCESS_LOGS"
  resource_arn = cloudfront_example.arn
}

AWS CLIコマンドで設定値を次のコマンドで確認できます。

aws logs describe-delivery-sources --region us-east-1

{
    "deliverySources": [
        {
            "name": "delivery_source-example-name",
            "arn": "arn:aws:logs:us-east-1:012345678901:delivery-source:delivery_source-example-name",
            "resourceArns": [
                "arn:aws:cloudfront::012345678901:distribution/example"
            ],
            "service": "cloudfront",
            "logType": "ACCESS_LOGS"
        }
    ]
}

配信先(Delivery Destination)の作成

配信先としてS3バケットを設定しますので、宛先 arn に保存先のS3バケット arn を指定し、ログフォーマット形式(output_format)を w3c に設定しています。

resource "aws_cloudwatch_log_delivery_destination" "s3_destination" {
  provider = aws.us_east_1

  name          = "cloudfront-s3-destination"
  output_format = "w3c"

  delivery_destination_configuration {
    destination_resource_arn = aws_s3_bucket.cloudfront_logs.arn
  }
}

AWS CLIコマンドで設定値を次のコマンドで確認できます。

aws logs describe-delivery-destinations --region us-east-1

{
    "deliveryDestinations": [
        {
            "name": "cloudfront-s3-destination",
            "arn": "arn:aws:logs:us-east-1:012345678901:delivery-destination:cloudfront-s3-destination",
            "deliveryDestinationType": "S3",
            "outputFormat": "w3c",
            "deliveryDestinationConfiguration": {
                "destinationResourceArn": "arn:aws:s3:::cloudfront-logs"
            }
        }
    ]
}

配信(Delivery)の作成

配信先に送信するログフィールドを設定します。

w3c ログフォーマットの中からapacheのCombined形式に近づけた形で選定しています。

resource "aws_cloudwatch_log_delivery" "cloudfront_to_s3" {
  provider = aws.us_east_1

  delivery_source_name     = aws_cloudwatch_log_delivery_source.cloudfront_access_logs.name
  delivery_destination_arn = aws_cloudwatch_log_delivery_destination.s3_destination.arn

  field_delimiter = " "

  record_fields = [
    "c-ip",
    "date",
    "time",
    "cs-method",
    "cs-uri-stem",
    "cs-uri-query",
    "cs-protocol-version",
    "sc-status",
    "sc-bytes",
    "cs(Referer)",
    "cs(User-Agent)"
  ]

  s3_delivery_configuration {
    enable_hive_compatible_path = false
    suffix_path                 = ""
  }
}

AWS CLIコマンドで設定値を次のコマンドで確認できます。

aws logs describe-deliveries --region us-east-1

{
    "deliveries": [
        {
            "id": "quBjMb62UbjYfWVq",
            "arn": "arn:aws:logs:us-east-1:012345678901:delivery:quBjMb62UbjYfWVq",
            "deliverySourceName": "delivery_source-example-name",
            "deliveryDestinationArn": "arn:aws:logs:us-east-1:012345678901:delivery-destination:cloudfront-s3-destination"
        }
    ]
}

S3 バケットポリシー設定

標準ログ記録 (v2) では、「delivery.logs.amazonaws.com」からS3バケットに対して書き込みするS3バケットポリシーを定義する必要があるため下記に示すポリシーを設定します。

resource "aws_s3_bucket_policy" "destination_bucket_policy" {
  bucket = aws_s3_bucket.destination.id

  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "AWSLogDeliveryWrite20150319"
    Statement = [
      {
        Sid    = "AWSLogDeliveryWrite1"
        Effect = "Allow"
        Principal = {
          Service = "delivery.logs.amazonaws.com"
        }
        Action   = "s3:PutObject"
        Resource = "${aws_s3_bucket.destination.arn}/*"
        Condition = {
          StringEquals = {
            "aws:SourceAccount" = 012345678901
            "s3:x-amz-acl"      = "bucket-owner-full-control"
          }
          ArnLike = {
            "aws:SourceArn" = "arn:aws:logs:us-east-1:012345678901:delivery-source:delivery_source-example-name"
          }
        }
      }
    ]
  })

  depends_on = [aws_s3_bucket_public_access_block.destination]
}

設定後の画面

Terraform でAWS環境に適用後、CloudFrontの標準ログ画面に下記に示す画像になっていることが確認できます。

適切にログフィールドが選択されており期待した結果になっていることが確認できます。

実際に記録されるログ内容

実際に記録されるS3へのファイル名とログ内容を紹介します。

  • S3バケットに記録されるログファイル名

  • 記録されたログ内容
#Version: 1.0
#Fields: c-ip date time cs-method cs-uri-stem cs-uri-query cs-protocol-version sc-status sc-bytes cs(Referer) cs(User-Agent)
xxx.xxx.xxx.xxx 2000-01-12 09:30:53 GET / - HTTP/2.0 200 688 - Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/138.0.0.0%20Safari/537.36%20Edg/138.0.0.0

まとめ

CloudFrontのログ記録いかがでしたでしょうか。

なるべくレガシーではなく非レガシーで設定していきたいですよね。