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

使用Terraform配置CloudFront对接双S3存储桶的路由故障排查

问题分析与解决方案

一、资源路径404错误的原因及修复

1. 核心冲突:Origin Path与路由路径的不匹配

你的CloudFront配置中,resources存储桶的origin设置了origin_path = "/resources",同时对应的ordered_cache_behavior路径模式为"resources*"。这会导致:

  • 用户请求https://dablogga.zenithgamesfoundry.com/resources/mike2_small.png时,CloudFront匹配到该行为后,会自动在请求路径前追加/resources,最终转发到S3的路径变成/resources/resources/mike2_small.png。
  • 而你的文件实际存储在resources桶的根目录,S3找不到该路径,因此返回404。

2. 修复步骤

移除Origin Path配置

删除resources origin中的origin_path = "/resources",因为文件并不在桶的resources子目录下:

origin {
  domain_name = "${aws_s3_bucket.resources.id}.s3-website-${aws_s3_bucket.resources.region}.amazonaws.com"
  origin_id   = "s3-${aws_s3_bucket.resources.id}"
  # 移除此行:origin_path = "/resources"

  custom_origin_config {
    http_port                = 80
    https_port               = 443
    origin_keepalive_timeout = 5
    origin_protocol_policy   = "http-only"
    origin_read_timeout      = 30
    origin_ssl_protocols     = ["TLSv1.2"]
  }
}

优化路径模式(可选)

将path_pattern改为"resources/*",确保只匹配/resources/开头的路径,避免误匹配类似resources.html这类文件:

ordered_cache_behavior {
  allowed_methods = ["GET", "HEAD", "OPTIONS"]
  cached_methods  = ["GET", "HEAD", "OPTIONS"]
  path_pattern            = "resources/*" # 修改此处
  target_origin_id        = "s3-${aws_s3_bucket.resources.id}"
  viewer_protocol_policy  = "redirect-to-https"
  compress                = true
  forwarded_values {
    query_string = true
    cookies {
      forward = "all"
    }
    headers = ["Access-Control-Request-Headers", "Access-Control-Request-Method", "Origin"]
  }
}

验证文件存储路径

确认resources桶中的文件直接存储在根目录,而非resources子文件夹。如果文件确实存于子目录,则需保留origin_path并确保请求路径与存储路径一致。

二、基于域名的路由切换实现

可以通过两种方式实现CloudFront基于域名的路由:

方案1:使用Cache Behavior的Host Header条件

利用CloudFront的条件匹配功能,针对特定域名设置专属路由:

  1. 确保CloudFront的aliases已包含两个目标域名(当前配置已满足)。
  2. 添加针对resources域名的ordered_cache_behavior,放在默认behavior之前(CloudFront按顺序匹配行为):
ordered_cache_behavior {
  allowed_methods = ["GET", "HEAD", "OPTIONS"]
  cached_methods  = ["GET", "HEAD", "OPTIONS"]
  path_pattern            = "*"
  target_origin_id        = "s3-${aws_s3_bucket.resources.id}"
  viewer_protocol_policy  = "redirect-to-https"
  compress                = true
  # 匹配resources域名的Host头
  condition {
    name = "HostHeader"
    values = ["${var.resources_domain}"]
  }
  forwarded_values {
    query_string = true
    cookies {
      forward = "all"
    }
    headers = ["Host", "Access-Control-Request-Headers", "Access-Control-Request-Method", "Origin"]
  }
}

方案2:使用Lambda@Edge(更灵活)

创建Lambda@Edge函数在请求阶段根据Host头切换origin:

  1. 在us-east-1区域创建Lambda函数:
exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const hostHeader = request.headers.host[0].value;
  
  if (hostHeader === 'resources.dablogga.zenithgamesfoundry.com') {
    request.origin.custom.domainName = 'resources.dablogga.zenithgamesfoundry.com.s3-website-ap-southeast-2.amazonaws.com';
    request.origin.custom.path = '';
  } else {
    request.origin.custom.domainName = 'dablogga.zenithgamesfoundry.com.s3-website-ap-southeast-2.amazonaws.com';
    request.origin.custom.path = '';
  }
  
  callback(null, request);
};
  1. 将函数关联到CloudFront的viewer-request事件。

三、额外注意事项

  • 403错误通常由S3权限问题导致,当前resources桶的ACL和Public Access Block配置已正确,无需调整。
  • CloudFront配置修改后需等待10-15分钟分发生效。
  • 可通过CloudFront实时日志或访问日志排查请求转发是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:25:53