从 VPC 中的 Lambda 访问 AWS S3
Posted
技术标签:
【中文标题】从 VPC 中的 Lambda 访问 AWS S3【英文标题】:Access AWS S3 from Lambda within VPC 【发布时间】:2017-02-08 08:23:34 【问题描述】:总的来说,我对在 VPC 中使用 AWS Lambda 感到很困惑。问题是 Lambda 在尝试访问 S3 存储桶时超时。解决方案似乎是 VPC Endpoint。
我已将 Lambda 函数添加到 VPC,以便它可以访问 RDS 托管数据库(以下代码中未显示,但功能正常)。但是,现在我无法访问 S3,并且任何尝试这样做都会超时。
我尝试创建 VPC S3 端点,但没有任何改变。
VPC 配置
每当我第一次创建 EC2 实例时,我都会使用默认创建的简单 VPC。它有四个子网,都是默认创建的。
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)
【问题讨论】:
VPC S3 端点需要路由表配置和安全策略配置。如果您需要帮助,您需要展示您是如何配置这些设置的。文档在这里:docs.aws.amazon.com/AmazonVPC/latest/UserGuide/… 或者,您可以向 VPC 添加一个 NAT 网关,这将使 Lambda 函数可以访问 VPC 之外的所有内容,而不仅仅是 S3 服务。 这是 vpc 配置问题。在路由表上配置任何一个与 nat 网关的 sbunet 关联。你还在寻找问题吗? 我添加了一些关于 VPC 配置的信息。我认为这就是问题所在,但 VPC 在很大程度上对我来说是一个黑匣子。我不知道用它检查什么以查看可能配置错误的内容。 【参考方案1】:还有另一个与 VPC 端点相关的解决方案。
在 AWS 控制台上,选择 VPC 服务,然后选择终端节点。创建一个新端点,将其关联到 s3 服务
VPC S3 endpoint selection
然后选择 VPC 和路由表。
然后选择访问级别(完整或自定义),它将起作用。
【讨论】:
感激不尽,花了一整天的时间来解决这个问题。它修复了!!! 在我将我的 Chalice 功能添加到 *** 并且 S3 刚刚停止连接后,让我非常头疼。 一开始我实际上忽略了这个答案,因为我认为它与创建新 VPC 相关,而实际上它与 endpoints 相关是我选择了gateway
选项而不是interface
选项,因为VPC 定价页面明确指出VPC 端点网关没有成本(不确定接口)。请注意,网关和接口都将具有相同的服务名称。在我的情况下是“com.amazonaws.us-east-2.s3”
这对我来说也是如此,简单而简单,我的s3.get_object
调用没有任何变化,而且我仍然可以使用https://
url 访问文件。
像魅力一样工作。非常感谢。【参考方案2】:
使用 boto3,S3 url 默认为 virtual,这需要将互联网访问解析为特定于区域的 url。这会导致 Lambda 函数挂起,直到超时。
要解决这个问题,需要在创建客户端时使用 Config
对象,这会告诉 boto3 创建基于 path 的 S3 url:
import boto3
import botocore
client = boto3.client('s3', 'ap-southeast-2', config=botocore.config.Config(s3='addressing_style':'path'))
请注意,调用中的区域必须是您要部署 lambda 和 VPC Endpoint 的区域。
然后您将能够在 Lambda 的安全组中为 VPC 端点使用 pl-xxxxxx
前缀列表,并且仍然可以访问 S3。
这是一个有效的CloudFormation script 演示了这一点。它会创建一个 S3 存储桶、一个与仅包含私有子网和 VPC 端点以及必要的 IAM 角色的 VPC 关联的 lambda(将记录放入存储桶)。
【讨论】:
node.js aws-sdk 有类似的设置吗?我看到了s3ForcePathStyle,但它似乎不起作用。 您的导入语句中有错字。应该是:import botocore
然后下一行应该按预期工作。
sn-p 中的错字,'ap-southeast-2'
中的单引号应关闭。
使用boto3.Session()
时该怎么办?这个参数怎么传?
你是一个学者,一个绅士。谢谢你的回答!【参考方案3】:
还有一个与子网和路由有关的问题在其他答案中未解决,因此我正在创建一个单独的答案,但前提是上述所有答案都适用。您必须正确设置它们才能让 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 中拥有两个子网,这也是一个好主意。
【讨论】:
要在 AWS 控制台中创建终端节点,请转到 VPC 仪表板 > 终端节点 我认为这行不通,将采用 igw 路线,但这将丢弃 ref docs.aws.amazon.com/vpc/latest/userguide/…【参考方案4】:我的问题的原因是没有正确配置我的安全组的出站规则。具体来说,我需要添加目的地为 pl-XXXXXXXX(S3 服务。实际值由 AWS 控制台提供)的自定义协议出站规则。
【讨论】:
你能举例说明如何做到这一点,因为即使我也面临同样的问题pl-xxx
看起来像一个前缀列表,如下所述:docs.aws.amazon.com/AmazonVPC/latest/UserGuide/…,可以在命令行中使用aws ec2 describe-prefix-lists
找到。
最后我只是为那个 lambda 函数创建了一个安全组:aws ec2 create-security-group --group-name my-lambda --description 'Good luck' --vpc-id vpc-123456
我应用了那个组,没有其他。出口规则是唯一重要的规则。如果你不给,一切都是允许的。我对此不太满意,但代码很小且可审计,我无法让严格的控制正常工作。如果代码变得更复杂,我将不得不重新审视这一点。
如果您将所有端口的安全组的出站规则设置为 0.0.0.0/0,这应该可以工作,对吧?因为download_fileobj
还只是挂着
太棒了!!谢谢,我还完美配置了 VPC 子网和路由表,但忘记了安全网关可以阻止它,以便指出它。【参考方案5】:
我只是想在其他答案中添加一个其他答案,这可能会影响那些冷启动时间很慢的正在运行的功能。
我已按照有关为 S3 设置网关的所有说明进行操作,但仍然无法正常工作。我创建了一个测试 Node.js 函数,它简单地列出了存储桶 - 我验证了如果没有 S3 网关,这不起作用,但一旦建立了网关就可以了。所以我知道部分事情运行良好。
在调试时,我正在更改函数的超时时间以确保函数已更新,并且在调用和测试时我使用的是最新版本的代码。
我已将超时时间减少到 10 秒,但结果表明我的功能在冷启动时需要更像 15 秒。 一旦我再次增加超时,它就起作用了。
【讨论】:
【参考方案6】:要从 VPC 中的 Lambda 函数访问 S3,您可以使用 Natgateway(与 VPC 终端节点相比,这是一种非常昂贵的解决方案)。如果您在 VPC 中有两个私有子网(其中子网有到 NAT 网关的路由)并将它们与 Lambda 相关联,则它可以像访问 VPC 外部的任何 Lambda 一样访问 S3 存储桶。 陷阱
-
如果您将公有子网与 Lambda 相关联,期望它能够工作,但它不会。
确保您的安全组已准备好接受入口。
这种方法将使 Lambda 函数可以访问 Internet 上的任何可用服务。详细步骤可以关注这个博客https://blog.theodo.com/2020/01/internet-access-to-lambda-in-vpc/
【讨论】:
以上是关于从 VPC 中的 Lambda 访问 AWS S3的主要内容,如果未能解决你的问题,请参考以下文章
AWS Lambda 无法访问同一 VPC 中的 EC2 端口
VPC 中的 AWS Lambda 在 NAT 之后没有互联网访问权限
如何从账户 A 中的 Lambda(VPC 中的 Lambda)调用账户 B 中的 AWS Lambda 函数(VPC 中的这个 Lambda)
AWS Lambda:如何为具有 VPC 访问权限的 lambda 函数设置 NAT 网关