22

我使用构建的数据处理管道

S3 + SNS + Lambda

因为 S3 无法将通知发送到其存储区域之外,所以我利用 SNS 将 S3 通知发送到其他区域的 Lambda。

lambda 函数编码为

from __future__ import print_function
import boto3


def lambda_handler (event, context):
    input_file_bucket = event["Records"][0]["s3"]["bucket"]["name"]
    input_file_key = event["Records"][0]["s3"]["object"]["key"]

    input_file_name = input_file_bucket+"/"+input_file_key

    s3=boto3.resource("s3")
    obj = s3.Object(bucket_name=input_file_bucket, key=input_file_key)
    response = obj.get()

    return event #echo first key valuesdf

当我运行保存和测试时,出现以下错误

    {
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      20,
      "lambda_handler",
      "response = obj.get()"
    ],
    [
      "/var/runtime/boto3/resources/factory.py",
      394,
      "do_action",
      "response = action(self, *args, **kwargs)"
    ],
    [
      "/var/runtime/boto3/resources/action.py",
      77,
      "__call__",
      "response = getattr(parent.meta.client, operation_name)(**params)"
    ],
    [
      "/var/runtime/botocore/client.py",
      310,
      "_api_call",
      "return self._make_api_call(operation_name, kwargs)"
    ],
    [
      "/var/runtime/botocore/client.py",
      395,
      "_make_api_call",
      "raise ClientError(parsed_response, operation_name)"
    ]
  ],
  "errorType": "ClientError",
  "errorMessage": "An error occurred (AccessDenied) when calling the GetObject operation: Access Denied"
}

我配置了 lambda 角色

full S3 access

并在我的目标存储桶上设置存储桶策略

everyone can do anything(list, delete, etc.)

看来我没有好好制定政策。

4

7 回答 7

22

Omuthu 的回答实际上正确地确定了我的问题,但它没有提供解决方案,所以我想我会这样做。

当您在 IAM 中设置权限时,您可能会进行如下操作:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test"
            ]
        }
    ]
}

不幸的是,这是不正确的。您需要对存储桶中的对象应用对象权限。所以它必须看起来像这样:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::test/*"
            ]
        }
    ]
}

/*请注意末尾带有 的第二个 ARN 。

于 2018-05-19T18:20:27.137 回答
18

我有一个类似的问题,我通过将适当的策略附加到我的用户来解决它。

IAM -> 用户 -> 用户名 -> 权限 -> 附加策略。

还要确保添加正确的访问密钥和秘密访问密钥,您可以使用 AmazonCLI 来完成。

于 2016-02-01T02:11:09.343 回答
8

您正在寻找的特定 S3 对象的可能性是具有有限的权限

  1. S3 对象级读取权限被拒绝
  2. 附加到 lambda 的角色没有获取/读取 S3 对象的权限
  3. 如果使用 S3 存储桶策略授予访问权限,请验证是否提供了读取权限
于 2015-11-07T19:49:28.100 回答
6

我有类似的问题,不同之处在于存储桶是用 KMS 密钥加密的。

已修复:IAM -> 加密密钥 -> YOUR_AWS_KMS_KEY -> 到您的策略或帐户

于 2018-07-26T03:58:25.883 回答
6

添加到 Amri 的答案中,如果您的存储桶是私有的并且您拥有访问它的凭据,则可以使用 boto3.client:

import boto3
s3 = boto3.client('s3',aws_access_key_id='ACCESS_KEY',aws_secret_access_key='SECRET_KEY')
response = s3.get_object(Bucket='BUCKET', Key='KEY')

*对于这个文件:s3://bucket/a/b/c/some.text,Bucket是'bucket',Key是'a/b/c/some.text'

- -编辑 - -

例如,您可以轻松更改脚本以接受密钥作为环境变量,这样它们就不会被硬编码。为了简单起见,我这样离开

于 2017-03-14T11:43:17.187 回答
1

就我而言 - 我正在运行的 Lambda 有一个角色blahblahRole,它blahblahRole没有 S3 存储桶的权限。

于 2019-08-04T17:15:49.890 回答
1

以下是一个简单的 JSON IAM 片段,可以添加到IAM Role. 虽然这给FullAccess了存储桶,但通常不应该成为问题,因为专用存储桶用于生产中的 Lambda 操作。

但是,如果FullAccess不希望抛出AccessDenied错误的任何操作,则需要单独添加这些操作。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAllOnThisBucket",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": "arn:aws:s3:::bucket_name/*"
        }
    ]
}
于 2022-02-22T14:51:44.623 回答