在VPC

时间:2016-09-29 21:01:24

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

总的来说,我对在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)

6 个答案:

答案 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 S3 endpoint selection

,然后选择VPC和路由表。

然后选择访问级别(完全或自定义),它将起作用。

答案 4 :(得分:0)

我只是想在其他答案中添加一个答案,这可能会影响那些启动时间较慢的正在运行的功能。

我已经按照有关为S3设置网关的所有说明进行操作,但是仍然无法正常工作。我创建了一个测试Node.js函数,该函数仅列出了存储桶-我验证了没有S3网关这是行不通的,但是一旦网关建立就可以了。所以我知道部分事情运行良好。

在调试时,我在更改函数的超时时间以确保功能已更新,并且在调用和测试时使用的是最新版本的代码。

我将超时减少到10s,只是事实证明我的功能在冷启动时需要更多的时间,例如15s。 一旦我再次增加了超时,它就会起作用。

答案 5 :(得分:0)

要从VPC内的Lambda函数中访问S3,可以使用Natgateway(与VPC端点相比,这是一个非常昂贵的解决方案)。如果您在VPC内有两个私有子网(子网具有到NAT网关的路由)并将它们与Lambda关联,则它可以像访问VPC之外的任何Lambda一样访问S3存储桶。 陷阱

  1. 如果您将公共子网与Lambda关联,希望它能正常工作,则不会。
  2. 确保您的安全组已就绪,可以接受入侵。

此方法将使Lambda函数可以访问Internet上的任何服务。有关详细步骤,您可以关注此博客https://blog.theodo.com/2020/01/internet-access-to-lambda-in-vpc/