【问题标题】:AWS Lamda: ClientError: An error occurred (403) when calling the HeadObject operation: ForbiddenAWS Lamda:ClientError:调用 HeadObject 操作时发生错误(403):禁止
【发布时间】:2021-05-06 13:00:19
【问题描述】:

我是AWS 的新手。我正在尝试使用以下AWS 服务处理xlsx 文件。 S3 Bucket,用来存储文件,SNS 订阅AWS Lamda 写在Python 中的函数。所以这是我的一段代码:

import json
import boto3
import pandas as pd
import os, tempfile
import sys
import uuid
from urllib.parse import unquote_plus

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    print('coming here')
    message = event['Records'][0]['Sns']['Message']
    bucket = 'bucket1'
    newbucket = 'bucket2'
    jmessage = json.loads(message)
    key = unquote_plus(jmessage["Records"][0]['s3']['object']['key'])
    directory_name = tempfile.mkdtemp()
    download_path = os.path.join(directory_name, 'EXAMPLE2.xlsx')
    print(download_path)
    newkey= 'cleaned.csv'
    upload_path = os.path.join(directory_name, newkey)
    s3_client.download_file(bucket, key, download_path)
    df = pd.read_Excel(download_path, skiprows=3)
    header2 = ['K', 'GEN STATUS']
    df.to_csv(upload_path, columns=header2, index=False)
    s3_client.upload_file(upload_path, newbucket, newkey)

    sns = boto3.client('sns')
    response = sns.publish(
        TopicArn='arn:aws:lambda:us-east-1:<id>:function:DataClean',
        Message='Data is cleaned and save into bucket Cleaned-data. Auto data ingestion is running.'
    )
    return {
        'statusCode': 200,
        'body': json.dumps('Done with cleansing!!')
    }

当我将xlsx 文件上传到s3 存储桶时,SNS 会触发上述Lambda 函数,但会呈现以下错误:

[ERROR] ClientError: 调用时发生错误 (403) HeadObject 操作:Forbidden Traceback(最近一次调用最后一次):
文件“/var/task/lambda_function.py”,第 23 行,在 lambda_handler s3_client.download_file(bucket, key, download_path)

这是完整的日志:

2021-02-02T12:16:34.838+05:00


[ERROR] ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 23, in lambda_handler
    s3_client.download_file(bucket, key, download_path)
  File "/var/runtime/boto3/s3/inject.py", line 172, in download_file
    extra_args=ExtraArgs, callback=Callback)
  File "/var/runtime/boto3/s3/transfer.py", line 307, in download_file
    future.result()
  File "/var/runtime/s3transfer/futures.py", line 106, in result
    return self._coordinator.result()
  File "/var/runtime/s3transfer/futures.py", line 265, in result
    raise self._exception
  File "/var/runtime/s3transfer/tasks.py", line 255, in _main
    self._submit(transfer_future=transfer_future, **kwargs)
  File "/var/runtime/s3transfer/download.py", line 343, in _submit
    **transfer_future.meta.call_args.extra_args
  File "/var/runtime/botocore/client.py", line 357, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 676, in _make_api_call
    raise error_class(parsed_response, operation_name)

这就是我的存储桶策略的样子:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<id>:root"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucket1/*"
        }
    ]
}

那么这里出了什么问题?

【问题讨论】:

    标签: python amazon-web-services amazon-s3 amazon-sns


    【解决方案1】:

    您的 lambda 角色无权访问 S3 存储桶来下载对象。

    Tutorial: Using AWS Lambda with Amazon S3

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "logs:PutLogEvents",
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream"
                ],
                "Resource": "arn:aws:logs:*:*:*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject"
                ],
                "Resource": "arn:aws:s3:::bucket1/*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "s3:PutObject"
                ],
                "Resource": "arn:aws:s3:::bucket2/*"
            }
        ]
    }         
            
    

    NOTE:确保(IAM 角色和您的 S3 存储桶策略)都允许您的 lambda。

    Identity-based policies and resource-based policies

    【讨论】:

    • 如何授予对 Lambda 的访问权限以下载对象?我是 AWS 新手,请多多包涵。我还使用 s3 存储桶策略编辑了问题。
    • @Saani 我将文档链接附加到答案中,看看。我可以帮你解决这个问题。
    • @Saani 在您的政策中允许使用一个存储桶,但在代码中您有两个存储桶 bucket = 'bucket1' newbucket = 'bucket2'
    • @Saani 如果这对您有用,您是否可以将此问题标记为已解决。这有助于社区和将来偶然发现这个问题的任何人。
    • 是的,我会继续尝试实施解决方案。仍然得到同样的错误。我尝试按照您建议的教程进行操作。
    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 2020-06-07
    • 2022-10-04
    • 2022-11-11
    • 2019-05-23
    • 2021-02-13
    相关资源
    最近更新 更多