如何配置S3 Bucket以允许AWS Application Load Balancer(非经典型)访问并启用日志?遇访问拒绝错误
解决Application Load Balancer日志投递到S3的Access Denied问题
你遇到的问题核心是:Application Load Balancer(ALB)的日志投递使用的是服务主体(Service Principal)而非经典负载均衡器的IAM服务账号。经典LB的aws_elb_service_account数据源不适用于ALB,我们需要调整S3桶的权限策略来适配ALB的日志投递需求。
正确的配置步骤
ALB的日志投递服务身份是logdelivery.elb.amazonaws.com,我们需要给这个服务主体配置上传日志到S3桶的权限,并且必须满足AWS要求的ACL条件。以下是完整的修正后Terraform代码:
resource "aws_s3_bucket" "lb-logs" { bucket = "yeo-messaging-${var.environment}-lb-logs" # 确保桶名全局唯一 } resource "aws_s3_bucket_acl" "lb-logs-acl" { bucket = aws_s3_bucket.lb-logs.id acl = "private" } # 为ALB日志投递配置S3桶权限策略 data "aws_iam_policy_document" "allow-lb" { statement { principals { type = "Service" # ALB日志投递的服务主体,替换经典LB的服务账号 identifiers = ["logdelivery.elb.amazonaws.com"] } # ALB只需要上传日志的权限,无需读取/列出桶 actions = [ "s3:PutObject" ] # 权限作用于桶内的所有对象(日志会上传到前缀路径下) resources = [ "${aws_s3_bucket.lb-logs.arn}/*" ] # AWS强制要求:必须设置x-amz-acl为bucket-owner-full-control,确保桶所有者拥有日志权限 condition { test = "StringEquals" variable = "s3:x-amz-acl" values = [ "bucket-owner-full-control" ] } } } resource "aws_s3_bucket_policy" "allow-lb" { bucket = aws_s3_bucket.lb-logs.id policy = data.aws_iam_policy_document.allow-lb.json } resource "aws_lb" "main" { name = "main" internal = false load_balancer_type = "application" security_groups = [aws_security_group.public.id] enable_deletion_protection = false subnets = [aws_subnet.public.id, aws_subnet.public-backup.id] access_logs { bucket = aws_s3_bucket.lb-logs.bucket prefix = "main-lb" enabled = true } }
关键修改说明
- 替换服务主体:把经典LB的IAM服务账号换成ALB专属的
logdelivery.elb.amazonaws.com服务主体,类型为Service而非AWS。 - 最小权限原则:只授予
s3:PutObject权限,ALB不需要读取或列出S3桶的权限。 - 强制ACL条件:添加
s3:x-amz-acl的条件检查,这是AWS的硬性要求,否则会因为权限不足导致日志投递失败。
额外注意事项
- 区域一致性:确保ALB和S3桶在同一个AWS区域,ALB不支持跨区域投递日志。
- 桶名唯一性:S3桶名是全球唯一的,如果你之前创建过同名桶,需要更换名称。
- 现有桶的权限清理:如果这个S3桶之前配置过其他策略,确保没有冲突的 deny 语句阻止ALB的日志投递。
内容的提问来源于stack exchange,提问作者SebastianG
相关产品推荐
相关产品推荐

