AWS Lambda无法从S3获取文件

3

你好,我有一个lambda函数(python3.6),它无法从S3中读取文件,尽管该lambda函数在拥有S3无限制权限的角色下运行(IAM策略如下)。

该Lambda函数仅尝试从S3中检索文件并将其写入临时位置。但是,在调用s3.Bucket()时会被阻塞并超时(即使设置了几分钟的超时时间)。

真正奇怪的是,它在没有任何异常的情况下超时,并且没有拒绝对s3.Bucket()的调用,也没有出现某种权限错误。

这很基础,但我不知道如何解决这个问题。

import boto3
from botocore import exceptions

def lambda_handler(event, context):
  key = event['image']
  bucket = event['bucket']
  tempfile = '/tmp/%s-%s' % (bucket, key)
  print('(p) bucket: %s::%s' % (bucket, key))
  print('(p) tempfile: %s' % tempfile)
  s3 = boto3.resource('s3')
  print('(p) resource intiialized')
  try:
    b = s3.Bucket(bucket) 
    print('(p) bucket info: %s [%s]' % (b.name, b.creation_date))
    b.download_file(prefixed_key, tempfile)
    print('(p} file downloaded to %s' % tempfile)
  except exceptions.ParamValidationError as e:
    return {"statusCode": 400, "body": 'ParamValidationError: [%s]' % e}
  except exceptions.ClientError as e:
    message = '[%s]: [%s]' % (e.response['Error']['Code'], e.response['Error']['Message'])
    return {"statusCode": e.response['ResponseMetadata']['HTTPStatusCode'], "body": message}
  print('(p) image downloaded from s3 and stored at: %s' % tempfile)
  return None

角色拥有的IAM策略如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my_bucket",
                "arn:aws:s3:::my_bucket/*"
            ]
        }
    ]
}

示例日志:

22:42:43
START RequestId: 61c60167-839d-11e7-97b1-a772bbde2609 Version: $LATEST
START RequestId: 61c60167-839d-11e7-97b1-a772bbde2609 Version: $LATEST
22:42:43
(p) bucket: my_bucket::my_key
22:42:43
(p) tempfile: /tmp/my_bucket/my_key
22:42:43
(p) resource intiialized
22:43:13
END RequestId: 61c60167-839d-11e7-97b1-a772bbde2609
END RequestId: 61c60167-839d-11e7-97b1-a772bbde2609

您的意思是Lambda函数本身超时了吗?您是否将函数超时时间从默认的3秒增加了?它是否在没有出站网络连接的VPC中运行? - jarmod
我已将函数超时设置为高达2分钟,并且Lambda本身已经超时。我添加了一些日志输出以说明。 - Edward Q. Bridges
没有任何异常消息。即使超时设置以分钟为单位,它也不会返回或完成执行。 - Edward Q. Bridges
尝试了以下方法但无效:https://dev59.com/61kS5IYBdhLWcg3we22Z#39797802 - Edward Q. Bridges
这里运行良好(直到遇到未初始化的prefixed_key编码错误)。您能否使用新的Python 3.6 Lambda函数重新开始,并使其真正简单(只需获取S3资源并调用硬编码桶名称的Bucket构造函数)? - jarmod
显示剩余3条评论
2个回答

0
问题被缩小到了VPC的错误配置上。我只需要将它配置为在VPC之外运行,因为现在我并不需要它,然后它就起作用了。

0

我曾经遇到过类似的问题,原因是我没有安装VPC网关端点。虽然我的VPC子网中的实例可以访问S3 URLS,但Lambda实例却不能。通过添加一个带有默认选项的VPC网关来允许我的子网使用它,问题得以解决。现在我的Lambda实例能够访问S3了。
与使用NAT网关相比,这是一种免费的选择。

另外,您需要确保已授予S3对象的权限。我将其设置为公共可读,可能有些过于宽松。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接