You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Terraform配置CloudFront高级S3日志记录?

用Terraform实现CloudFront日志高级配置(发送到S3)

一、传统S3访问日志的高级配置(对应GUI的高级选项)

你提到的Terraform logging_config块其实已经覆盖了GUI里的所有高级设置,只是可能没留意到扩展参数。以下是完整的配置示例,包含压缩、自定义日志字段、S3加密等选项:

resource "aws_cloudfront_distribution" "your_distribution" {
  # 这里填你已有的分发配置,比如origin、default_cache_behavior等

  logging_config {
    bucket         = aws_s3_bucket.log_bucket.bucket_domain_name
    enable         = true
    include_cookies = true # 对应GUI的"Include Cookies"
    prefix         = "cloudfront-access-logs/" # 日志存储前缀

    # 启用日志压缩(GUI的"Compress Logs")
    compress = true

    # 自定义日志字段(GUI的"Log Fields",按需选择)
    fields = [
      "date", "time", "c-ip", "sc-status", "cs-method",
      "cs-host", "cs-uri-stem", "cs-user-agent", "time-taken"
    ]

    # S3桶服务器端加密(GUI的"Server-Side Encryption")
    s3_bucket_config {
      bucket = aws_s3_bucket.log_bucket.id
      encryption_type = "aws:kms" # 可选"AES256"或"aws:kms"
      kms_key_id = aws_kms_key.log_encrypt_key.arn # 用KMS的话填ARN
    }
  }
}

# 日志S3桶及权限配置(CloudFront需要写入权限)
resource "aws_s3_bucket" "log_bucket" {
  bucket = "your-cloudfront-log-bucket" # 替换成你的桶名
}

resource "aws_s3_bucket_policy" "log_bucket_policy" {
  bucket = aws_s3_bucket.log_bucket.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = { Service = "cloudfront.amazonaws.com" }
        Action = "s3:PutObject"
        Resource = "${aws_s3_bucket.log_bucket.arn}/*"
        Condition = {
          StringEquals = { "AWS:SourceArn" = aws_cloudfront_distribution.your_distribution.arn }
        }
      }
    ]
  })
}

# 可选:KMS密钥用于日志加密
resource "aws_kms_key" "log_encrypt_key" {
  description = "Encrypt CloudFront access logs stored in S3"
}

二、实时日志转存S3(对应GUI的实时日志高级配置)

如果你的GUI操作是配置实时日志(先到Kinesis再转存S3),需要用aws_cloudfront_realtime_log_config资源,结合Kinesis Data Firehose完成转存:

# 1. 创建实时日志配置
resource "aws_cloudfront_realtime_log_config" "realtime_logs" {
  name = "your-cloudfront-realtime-logs"
  sampling_rate = 100 # 采样率1-100,100为全量
  fields = [
    "timestamp", "c-ip", "sc-status", "cs-method", "cs-host"
  ]

  endpoints {
    stream_type = "Kinesis"
    kinesis_stream_config {
      role_arn   = aws_iam_role.cloudfront_realtime_role.arn
      stream_arn = aws_kinesis_stream.log_stream.arn
    }
  }
}

# 2. 关联到CloudFront分发
resource "aws_cloudfront_distribution" "your_distribution" {
  # 已有分发配置...
  realtime_log_config_arn = aws_cloudfront_realtime_log_config.realtime_logs.arn
}

# 3. Kinesis Data Stream接收实时日志
resource "aws_kinesis_stream" "log_stream" {
  name = "cloudfront-realtime-log-stream"
  shard_count = 1
}

# 4. IAM角色允许CloudFront写入Kinesis
resource "aws_iam_role" "cloudfront_realtime_role" {
  name = "cloudfront-realtime-log-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = { Service = "cloudfront.amazonaws.com" }
        Action = "sts:AssumeRole"
        Condition = {
          StringEquals = { "AWS:SourceArn" = aws_cloudfront_realtime_log_config.realtime_logs.arn }
        }
      }
    ]
  })
}

resource "aws_iam_role_policy" "cloudfront_realtime_policy" {
  role = aws_iam_role.cloudfront_realtime_role.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      { Effect = "Allow", Action = "kinesis:PutRecord", Resource = aws_kinesis_stream.log_stream.arn }
    ]
  })
}

# 5. Kinesis Firehose将日志转存到S3
resource "aws_kinesis_firehose_delivery_stream" "log_to_s3" {
  name = "cloudfront-realtime-to-s3"
  destination = "s3"

  s3_configuration {
    role_arn        = aws_iam_role.firehose_role.arn
    bucket_arn      = aws_s3_bucket.log_bucket.arn
    prefix          = "realtime-logs/"
    compression_format = "GZIP"
    buffering_size  = 5 # MB
    buffering_interval = 300 # 秒
  }

  kinesis_stream_source_configuration {
    kinesis_stream_arn = aws_kinesis_stream.log_stream.arn
    role_arn           = aws_iam_role.firehose_role.arn
  }
}

# 6. Firehose所需IAM角色
resource "aws_iam_role" "firehose_role" {
  name = "firehose-cloudfront-log-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      { Effect = "Allow", Principal = { Service = "firehose.amazonaws.com" }, Action = "sts:AssumeRole" }
    ]
  })
}

resource "aws_iam_role_policy" "firehose_policy" {
  role = aws_iam_role.firehose_role.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow",
        Action = ["s3:PutObject", "s3:PutObjectAcl"],
        Resource = "${aws_s3_bucket.log_bucket.arn}/*"
      },
      {
        Effect = "Allow",
        Action = ["kinesis:GetRecords", "kinesis:GetShardIterator", "kinesis:DescribeStream"],
        Resource = aws_kinesis_stream.log_stream.arn
      }
    ]
  })
}

关键提示

  • 传统S3日志的logging_config已经包含GUI里的所有高级选项,之前没找到可能是忽略了compress、fields和s3_bucket_config这些参数。
  • 如果是实时日志需求,必须通过Kinesis中间层转存到S3,CloudFront不支持直接将实时日志发送到S3。

内容的提问来源于stack exchange,提问作者TheDemonLord

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:14:51