web-dev-qa-db-ja.com

AWS Lambda経由でboto3を使用してアクセスが拒否されました

私はで構成されたデータ処理パイプラインを使用します

S3 + SNS +ラムダ

s3はストレージ領域から通知を送信できないため、SNSを使用して他の領域のLambdaにS3通知を送信しました。

でコード化されたラムダ関数

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"
}

ラムダロールを構成しました

full S3 access

ターゲットバケットにバケットポリシーを設定します

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

ポリシーを適切に設定していないようです。

11
Hello lad

探している特定のS3オブジェクトの可能性は制限された権限を持っている

3
omuthu

同様の問題がありました。ユーザーに適切なポリシーを添付することで解決しました。

IAM->ユーザー->ユーザー名->権限->ポリシーをアタッチします。

また、正しいアクセスキーとシークレットアクセスキーを必ず追加してください。AmazonCLIを使用して追加できます。

13
Amri

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」、キーは「a/b/c/some.text」

4
Tal Joffe

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/*"
            ]
        }
    ]
}

最後に/*が付いた2番目のARNに注意してください。

4
Rob Rose

同様の問題がありました。違いは、バケットがKMSキーで暗号化されていたことです。

修正:IAM->暗号化キー-> YOUR_AWS_KMS_KEY->ポリシーまたはアカウント

1
MiaeKim

私の場合、私が実行していたLambdaにはblahblahRoleというロールがあり、このblahblahRoleにはS3バケットに対する権限がありませんでした。

0
VIPIN KUMAR