配置S3事件触发Lambda时遇Access Denied错误求助
问题:配置S3事件触发器到Lambda时出现权限拒绝错误
尝试为已配置S3权限的Lambda函数添加S3事件触发器时,报错:An error occurred while listing S3 relations: Access Denied
lambda.tf 配置
resource "aws_lambda_function" "s3-lambdas" { filename = "./s3-lambdas.zip" function_name = "s3-lambdas" source_code_hash = filebase64sha256(s3-lambdas) role = module.lambda_role.arn handler = "s3-lambdas.lambda_handler" runtime = "python3.9" timeout = 200 description = "invoke glue job" depends_on = [module.lambda_role] } resource "aws_lambda_permission" "s3_lambdas_s3_events" { depends_on = [aws_lambda_function.s3-lambdas] statement_id = "AllowS3Invoke" action = "lambda:InvokeFunction" function_name = aws_lambda_function.s3-lambdas.function_name principal = "s3.amazonaws.com" source_arn = "arn:aws:s3:::${module.bucket-name.name}" } resource "aws_s3_bucket_notification" "bucket_notifications" { bucket = module.bucket-name.name lambda_function { lambda_function_arn = aws_lambda_function.s3-lambdas.arn events = ["s3:ObjectCreated:*"] filter_prefix = "abc/def/" } depends_on = [aws_lambda_permission.s3_lambdas_s3_events] }
Lambda角色的S3权限策略(s3.tf)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "arn:aws:s3:::dev-s3-bucket", "arn:aws:s3:::dev-s3-bucket/*" ] } ] }
模块输出信息
output "bucket_name" { value = module.bucket-name.name } bucket_name = dev-s3-bucket output "iam_dev_arn" { value = module.lambda_role.arn } iam_dev_arn = arn:aws:iam::0123456789:role/s3-lambda-role output "div_arn" { value = aws_lambda_function.s3-lambdas.arn } div_arn = arn:aws:lambda:us-east-1:0123456789:function:s3-lambdas
Lambda角色信任策略(assume_role_policy)
{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
Lambda函数代码(s3-lambdas)
from __future__ import print_function import boto3 import urllib import os print ('Loading function') glue = boto3.client('glue') def lambda_handler(event, context): gluejobname = os.environ['glue_job'] try: runId = glue.start_job_run(JobName=gluejobname) status = glue.get_job_run(JobName=gluejobname, RunId=runId['JobRunId']) print("Job Status : ", status['JobRun']['JobRunState'], "runId",runId) except Exception as e: raise e return { "statusCode": 200, "body": os.environ['glue_job'] + " Job started" }
S3桶策略
{ "Version": "2012-10-17", "Statement": [ { "Sid": "denyInsecureTransport", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::dev-s3-bucket/*", "arn:aws:s3:::dev-s3-bucket" ], "Condition": { "Bool": { "aws:SecureTransport": "false" } } } ] }
排查与解决方法
1. 检查Terraform执行角色的权限
该错误出现在Terraform执行阶段,而非Lambda运行时,需确保执行Terraform的角色/用户拥有以下权限:
s3:GetBucketNotifications3:PutBucketNotificationlambda:GetPolicylambda:AddPermission
若使用本地AWS CLI执行,确认当前用户的IAM策略包含上述权限,且作用于对应的S3桶和Lambda资源。
2. 验证区域一致性
确认S3桶与Lambda函数处于同一AWS区域,跨区域配置S3事件触发器会导致权限或调用失败。
3. 检查桶策略的HTTPS限制
当前桶策略仅拒绝非HTTPS请求,若Terraform执行时使用HTTP通信(极少发生,默认AWS CLI用HTTPS)会触发拒绝,可确认本地AWS配置未强制禁用HTTPS。
4. 补充执行角色的S3通知权限
若执行Terraform的角色缺少S3桶通知相关权限,添加以下IAM策略语句:
{ "Effect": "Allow", "Action": [ "s3:GetBucketNotification", "s3:PutBucketNotification" ], "Resource": "arn:aws:s3:::dev-s3-bucket" }
内容的提问来源于stack exchange,提问作者Sayon
相关产品推荐
相关产品推荐

