首页 > 解决方案 > s3 存储桶不允许 PutObject

问题描述

我正在 s3 存储桶中保存一个 json 文件,并且我正在使用在 IAM 用户 cdeveloper 下创建的 lambda 函数。

资源政策是:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::355:user/cDeveloper"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::ag-grid/*"
        }
    ]
}

当我运行测试时,我得到:

START RequestId: abb632556 Version: $LATEST
An error occurred (AccessDenied) when calling the PutObject operation: Access Denied: ClientError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 24, in main
    run(event)
  File "/var/task/lambda_function.py", line 21, in run
    s3.Bucket('ag-grid').put_object(Key='assets/kpi.json', Body='kpi.json')
  File "/var/runtime/boto3/resources/factory.py", line 520, in do_action
    response = action(self, *args, **kwargs)
  File "/var/runtime/boto3/resources/action.py", line 83, in __call__
    response = getattr(parent.meta.client, operation_name)(**params)
  File "/var/runtime/botocore/client.py", line 314, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 612, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

这是我的功能:

r = requests.get('http://endpoint/', headers=headers).json() 

#save to temp folder
with open('kpi.json', 'w') as outfile:
    json.dump(r, outfile)
    s3 = boto3.resource('s3')
    s3.Bucket('ag-grid').put_object(Key='assets/kpi.json', Body='kpi.json')

我试过制作 Principal: * 并且它有效,但它对任何人开放。

标签: amazon-web-servicesamazon-s3aws-lambda

解决方案


您需要创建一个 IAM 角色并将该角色与 Lambda 函数相关联。

然后,要么:

  • 为角色分配访问 S3 存储桶的权限,或
  • 修改存储桶策略以引用角色的 ARN,而不是用户 ARN

最好将权限分配给角色,而不是为每个 Lambda 函数和存储桶修改存储桶策略。(即删除存储桶策略,将等价权限放入Role中。)


推荐阅读