使用Lambda和S3将数据插入存储桶时,AWS ClientError

时间:2020-06-03 03:25:25

标签: python amazon-web-services amazon-s3 aws-lambda

我正在尝试使用lambda将json blob放入S3存储桶中,并且在查看cloudwatch日志时遇到以下错误

[ERROR] ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
Traceback (most recent call last):
  File "/var/task/main.py", line 147, in lambda_handler
    save_articles_and_comments(sub, submissions)
  File "/var/task/main.py", line 125, in save_articles_and_comments
    object.put(Body=json.dumps(articles))
  File "/var/task/boto3/resources/factory.py", line 520, in do_action
    response = action(self, *args, **kwargs)
  File "/var/task/boto3/resources/action.py", line 83, in __call__
    response = getattr(parent.meta.client, operation_name)(*args, **params)
  File "/var/task/botocore/client.py", line 316, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/task/botocore/client.py", line 635, in _make_api_call
    raise error_class(parsed_response, operation_name)

所有块公共访问设置都设置为“关”,并且代码中的存储桶名称与S3中的相同。这是将json blob放入我的S3存储桶和lambda处理程序中可重新指定的文件夹中的代码

def save_articles_and_comments(sub, submissions):
    """
    """
    s3 = boto3.resource('s3')
    now = dt.datetime.utcnow()
    formatted_date = now.strftime("%Y-%m-%d-%H-%M-%S")

    articles, comments = data_for_subreddit(submissions)
    print("Number of articles, comments {}, {}".format(len(articles), len(comments)))
    articles_name = 'articles/' + formatted_date + '_' + sub + '_articles.json'
    comments_name = 'comments/' + formatted_date + '_' + sub + '_comments.json'
    object = s3.Object('diegos-reddit-bucket', articles_name)
    object.put(Body=json.dumps(articles))
    print("Finished writing articles to {}".format(articles_name))

    object = s3.Object('diegos-reddit-bucket', comments_name)
    object.put(Body=json.dumps(comments))
    print("Finished writing comments to {}".format(comments_name))


def lambda_handler(x, y):
    """
    """
    import time
    import random
    idx = random.randint(0, len(SUBREDDITS)-1)
    start = time.time()
    assert PRAW_KEY is not None
    sub = SUBREDDITS[idx]
    red = reddit_instance()
    subreddit = red.subreddit(sub)

    print("Pulling posts from {}, {}.".format(sub, "hot"))
    submissions = subreddit.hot()
    save_articles_and_comments(sub, submissions)
    print("="*50)

    print("Pulling posts from {}, {}.".format(sub, "new"))
    submissions = subreddit.new()
    save_articles_and_comments(sub, submissions)
    print("="*50)

    print("Pulling posts from {}, {}.".format(sub, "top"))
    submissions = subreddit.top()
    save_articles_and_comments(sub, submissions)
    print("="*50)

    print("Pulling posts from {}, {}.".format(sub, "rising"))
    submissions = subreddit.rising()
    save_articles_and_comments(sub, submissions)
    end = time.time()
    print("Elapsed time {}".format(end - start))

我没有看到代码中的问题让我得到上述错误。将我的lambda_handler函数换成一个main进行本地测试。通过主程序,它可以工作,并写入S3存储桶及其受尊重的文件夹。当我尝试通过AWS Lambda运行时,在函数完成从第一个subreddit提取帖子并尝试将json blob放入S3存储桶中的文件夹后,我得到了错误提示。这就是我的输出看起来应该是

Pulling posts from StockMarket, hot.
Number of articles, comments 101, 909
Finished writing articles to articles/2020-06-03-02-48-44_StockMarket_articles.json
Finished writing comments to comments/2020-06-03-02-48-44_StockMarket_comments.json
==================================================
Pulling posts from StockMarket, new.
Number of articles, comments 101, 778
Finished writing articles to articles/2020-06-03-02-49-10_StockMarket_articles.json
Finished writing comments to comments/2020-06-03-02-49-10_StockMarket_comments.json
==================================================
Pulling posts from StockMarket, top.
Number of articles, comments 101, 5116
Finished writing articles to articles/2020-06-03-02-49-36_StockMarket_articles.json
Finished writing comments to comments/2020-06-03-02-49-36_StockMarket_comments.json
==================================================
Pulling posts from StockMarket, rising.
Number of articles, comments 24, 170
Finished writing articles to articles/2020-06-03-02-52-10_StockMarket_articles.json
Finished writing comments to comments/2020-06-03-02-52-10_StockMarket_comments.json
Elapsed time 215.6588649749756

我的代码是否有问题,或者在AWS方面有问题?

1 个答案:

答案 0 :(得分:0)

发生此问题是因为您没有没有权限将对象写入存储桶:

PutObject 操作:访问被拒绝

要解决此问题,必须查看lambda execution role:它是否具有写入S3的权限?也可以检查存储桶策略。

主要使用它,并写入S3存储桶及其受尊敬的文件夹。当我尝试通过AWS Lambda运行时,出现错误提示

在本地测试时,您的代码正在使用您自己的权限(您的IAM用户)写入S3。这样就可以了。在lambda上执行代码时,您的函数未使用您的权限。而是使用 lambda执行角色中定义的权限。