Lambda函数读取S3 Bucket遇PermissionError Forbidden问题求助
我构建了一个运行ETL pipeline的Docker镜像,本地运行正常,但将镜像部署到AWS ECR后,调用该镜像的Lambda函数返回PermissionError: Forbidden错误。完整堆栈跟踪如下:
{ "errorMessage": "Forbidden", "errorType": "PermissionError", "requestId": "ed12c997-d1f7-4cba-8eaf-66b88643271c", "stackTrace": [ " File \"/var/task/app.py\", line 10, in handler\n main(now)\n", " File \"/var/task/scraper_backend/jobs/__init__.py\", line 15, in main\n df = transform.update_file(\n", " File \"/var/task/scraper_backend/jobs/transform.py\", line 24, in update_file\n df = read_file(path)\n", " File \"/var/task/scraper_backend/jobs/transform.py\", line 15, in read_file\n dataset = pq.ParquetDataset(f\"s3://{bucket}/{key}\", filesystem=fs)\n", " File \"/var/lang/lib/python3.9/site-packages/pyarrow/parquet/core.py\", line 1763, in __new__\n return _ParquetDatasetV2(\n", " File \"/var/lang/lib/python3.9/site-packages/pyarrow/parquet/core.py\", line 2452, in __init__\n finfo = filesystem.get_file_info(path_or_paths)\n", " File \"pyarrow/_fs.pyx\", line 571, in pyarrow._fs.FileSystem.get_file_info\n", " File \"pyarrow/error.pxi\", line 144, in pyarrow.lib.pyarrow_internal_check_status\n", " File \"pyarrow/_fs.pyx\", line 1490, in pyarrow._fs._cb_get_file_info\n", " File \"/var/lang/lib/python3.9/site-packages/pyarrow/fs.py\", line 330, in get_file_info\n info = self.fs.info(path)\n", " File \"/var/lang/lib/python3.9/site-packages/fsspec/asyn.py\", line 115, in wrapper\n return sync(self.loop, func, *args, **kwargs)\n", " File \"/var/lang/lib/python3.9/site-packages/fsspec/asyn.py\", line 100, in sync\n raise return_result\n", " File \"/var/lang/lib/python3.9/site-packages/fsspec/asyn.py\", line 55, in _runner\n result[0] = await coro\n", " File \"/var/lang/lib/python3.9/site-packages/s3fs/core.py\", line 1248, in _info\n out = await self._call_s3(\n", " File \"/var/lang/lib/python3.9/site-packages/s3fs/core.py\", line 348, in _call_s3\n return await _error_wrapper(\n", " File \"/var/lang/lib/python3.9/site-packages/s3fs/core.py\", line 140, in _error_wrapper\n raise err\n" ] }
我已在IAM控制台调整Lambda执行角色的权限策略,最初使用的策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetBucketLocation", "s3:ListAllMyBuckets" ], "Resource": "arn:aws:s3:::*" }, { "Effect": "Allow", "Action": "s3:*", "Resource": [ "arn:aws:s3:::my_bucket", "arn:aws:s3:::my_bucket/*" ] } ] }
之后尝试了另一套策略,问题仍未解决:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "ListObjectsInBucket", "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": ["arn:aws:s3:::my_bucket"] }, { "Sid": "AllObjectActions", "Effect": "Allow", "Action": "s3:*Object", "Resource": ["arn:aws:s3:::my_bucket/*"] } ] }
我已等待15-20分钟,不确定是否为策略生效时长问题,恳请提供排查思路。
排查思路
确认权限策略是否正确附加到Lambda执行角色
检查IAM控制台中Lambda对应的执行角色,确保你修改的策略已经成功附加,而非误操作到其他角色上。验证S3资源ARN的准确性
确认策略中的桶名称my_bucket完全匹配实际访问的S3桶,注意S3桶名区分大小写,同时检查对象路径是否与arn:aws:s3:::my_bucket/*的格式一致。检查S3桶的Bucket Policy
即使Lambda角色有允许权限,若S3桶自身的Bucket Policy存在拒绝规则(如IP限制、账户白名单等),会优先触发拒绝。进入S3桶的权限页面查看Bucket Policy,排除冲突规则。用IAM工具验证权限有效性
使用IAM的Access Advisor查看该角色的S3权限状态,或通过Policy Simulator模拟s3:GetObject、s3:ListBucket等具体动作,确认策略是否真的允许这些操作。检查代码中的凭证配置
本地运行可能依赖本地AWS凭证(如~/.aws/credentials),但Lambda默认使用执行角色的临时凭证。确认代码中没有硬编码其他凭证,或强制指定错误的凭证来源,导致s3fs无法正确获取Lambda角色权限。排查Lambda的VPC配置
若Lambda配置了VPC,需确保VPC能访问S3:要么配置NAT网关允许出站访问,要么添加S3 VPC网关端点。否则Lambda无法连接S3,也会表现为权限拒绝。通过CloudTrail定位具体拒绝事件
打开AWS CloudTrail,搜索Lambda执行角色的相关事件,找到AccessDenied记录,查看被拒绝的具体Action和Resource,精准定位权限缺失项。
内容的提问来源于stack exchange,提问作者david backx

