总的来说,我对在VPC中使用AWS Lambda感到非常困惑。问题是Lambda在尝试访问S3存储桶时超时。解决方案似乎是VPC端点。
我已将Lambda函数添加到VPC,因此它可以访问RDS托管数据库(未在下面的代码中显示,但功能正常)。但是,现在我无法访问S3,任何尝试都会超时。
我尝试创建一个VPC S3端点,但没有任何改变。
VPC配置
我使用默认创建的简单VPC,每当我第一次创建EC2实例时。它有四个子网,都是默认创建的。
VPC路线表
_Destination - Target - Status - Propagated_
172.31.0.0/16 - local - Active - No
pl-63a5400a (com.amazonaws.us-east-1.s3) - vpce-b44c8bdd - Active - No
0.0.0.0/0 - igw-325e6a56 - Active - No
简单S3下载Lambda:
import boto3
import pymysql
from StringIO import StringIO
def lambda_handler(event, context):
s3Obj = StringIO()
return boto3.resource('s3').Bucket('marineharvester').download_fileobj('Holding - Midsummer/sample', s3Obj)
答案 0 :(得分:12)
使用boto3时,S3网址默认为虚拟,然后需要将网络访问权限解析为特定于区域的网址。这导致挂起Lambda函数直到超时。
要解决此问题,需要在创建客户端时使用Config
对象,这告诉boto3创建基于S3网址的路径:
import boto3 import botocore.config
client = boto3.client('s3', 'ap-southeast-2, config=botocore.config.Config(s3={'addressing_style':'path'}))
请注意,调用中的区域必须是要部署lambda和VPC端点的区域。
然后,您将能够在Lambda的安全组中使用pl-xxxxxx
前缀列表作为VPC端点,并仍然可以访问S3。
这是一个有效的CloudFormation script来证明这一点。它创建一个S3存储桶,一个与仅包含私有子网和VPC端点的VPC相关联的lambda(将记录放入存储桶),以及必要的IAM角色。
答案 1 :(得分:4)
我的问题的原因是我的安全组的出站规则没有正确配置。具体来说,我需要添加自定义协议出站规则,目的地为pl-XXXXXXXX(S3服务。实际值由AWS控制台提供)。
答案 2 :(得分:4)
还有另一个问题与其他答案中没有解决的子网和路由有关,所以我创建了一个单独的答案,条件是所有上述答案都适用。你必须让它们适合lambda函数来访问S3。
当您创建我去年秋天创建的新AWS账户时,没有自动与您的默认VPC关联的路由表(请参阅路由表 - >控制台中的子网关联)。
因此,如果您按照instructions创建端点并为该端点创建路由,则不会添加任何路由,因为没有子网可以将其放置。和AWS一样,您不会收到错误消息......
您应该做的是为lambda函数创建一个子网,将该子网与路由表和lambda函数相关联,然后重新运行Endpoint指令,如果成功,您将找到一个包含三个条目的路由表这样:
Destination Target
10.0.0.0/16 Local
0.0.0.0/0 igw-1a2b3c4d
pl-1a2b3c4d vpce-11bb22cc
如果您只有两个条目(没有' pl-xxxxx'条目),那么您还没有成功。
最后我想,lambda函数需要一个子网才能生存,就像网络中的任何其他实体一样。并且可能建议它不与EC2实例位于同一子网上,因为lambda可能需要不同的路由或安全权限。请注意,lambda中的GUI真的希望你在两个不同的AZ中有两个子网,这也是一个好主意。
答案 3 :(得分:1)
还有另一种与VPC端点有关的解决方案。
在AWS Console上,选择VPC服务,然后选择Endpoints。创建一个新端点,将其关联到s3服务
,然后选择VPC和路由表。
然后选择访问级别(完全或自定义),它将起作用。
答案 4 :(得分:0)
我只是想在其他答案中添加一个答案,这可能会影响那些启动时间较慢的正在运行的功能。
我已经按照有关为S3设置网关的所有说明进行操作,但是仍然无法正常工作。我创建了一个测试Node.js函数,该函数仅列出了存储桶-我验证了没有S3网关这是行不通的,但是一旦网关建立就可以了。所以我知道部分事情运行良好。
在调试时,我在更改函数的超时时间以确保功能已更新,并且在调用和测试时使用的是最新版本的代码。
我将超时减少到10s,只是事实证明我的功能在冷启动时需要更多的时间,例如15s。 一旦我再次增加了超时,它就会起作用。
答案 5 :(得分:0)
要从VPC内的Lambda函数中访问S3,可以使用Natgateway(与VPC端点相比,这是一个非常昂贵的解决方案)。如果您在VPC内有两个私有子网(子网具有到NAT网关的路由)并将它们与Lambda关联,则它可以像访问VPC之外的任何Lambda一样访问S3存储桶。 陷阱
此方法将使Lambda函数可以访问Internet上的任何服务。有关详细步骤,您可以关注此博客https://blog.theodo.com/2020/01/internet-access-to-lambda-in-vpc/