【问题标题】:Can not access S3 via VPC endpoint in Lambda无法通过 Lambda 中的 VPC 端点访问 S3
【发布时间】:2018-11-04 14:08:36
【问题描述】:

我的 VPC 中有一个 Lambda 函数,我想访问 S3 存储桶。

我认为我已经正确设置了 S3 VPC 端点,因为我在与 Lambda 函数相同的子网和安全组中创建了一个 EC2 实例。当我在 EC2 实例上运行 Lambda 函数代码副本时,它可以正确显示 S3 文件内容。

但是当我在 Lambda 中运行代码时,它失败了。所以,我想知道“在 EC2 中运行”和“在 Lambda 中运行”有什么区别?为什么我在 Lambda 中运行它会失败?

这是我的 Lambda 函数代码:

    import boto3
    
    s3 = boto3.client('s3', region_name='ap-northeast-1')
    
    def lambda_handler(event, context):
        bucket = '*xxxxxx*'
        key = 's3-upload.json'
        try:
            response = s3.get_object(Bucket=bucket, Key=key)
            print('--------------------------------------')
            print(response)
            print('--------------------------------------')
            body = response['Body'].read()
            print(body)
            print('--------------------------------------')
            print("CONTENT TYPE: " + response['ContentType'])
            
        except Exception as e:
            print('Error getting object.')
            print(e)
            raise e

【问题讨论】:

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


    【解决方案1】:

    尽管 EC2 和 Lambda 在同一个 VPC 中,但它们在 AWS 中仍然是不同的环境。能够在一个而不是另一个中运行您的代码意味着您的代码很好并且可以工作,因此这可能是 AWS 的配置问题。

    您是否检查过 lambda 正在使用的服务/执行角色?

    您需要确保它使用的 IAM 角色被允许正确的 S3 访问级别。

    这份关于 lambda 执行角色的文档可能会提供一个有用的起点:https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role

    这样的 IAM 策略将授予您使用的任何执行角色对所有 S3 存储桶的只读访问权限,并且恰好是 AWS 托管策略之一。

    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": "*"
        }
    ]
    

    }

    【讨论】:

    • 谢谢,我的角色有“AmazonS3FullAccess”政策。
    • 嗯!那很奇怪,在我的 AWS 账户中运行相同的东西没有错误。您是否有任何错误消息可以添加到原始问题中?
    • @YOUNG 您是否将 vpc 端点条目附加到与您的子网关联的路由表。您是否也将角色分配给 lambda,您遇到了什么错误,是否存在权限问题或 s3 请求超时。
    • @Robin 错误信息只是“超时”。我的角色有完整的 s3 访问策略。我还将 vpc 端点规则添加到我的子网路由表(或者我的 ec2 代码访问 s3)。
    【解决方案2】:

    如果您想允许 AWS Lambda 访问 Amazon S3,请使用以下方法之一:

    • 不要将函数关联到 VPC。然后自动访问。
    • 如果函数附加到 VPC 中的公共子网,请将 弹性 IP 关联到 VPC 中显示的 Lambda 函数的 ENI(不推荐)
    • 如果函数附加到 VPC 中的私有子网,请在公共子网中启动 NAT 网关 并更新路由表。流量将通过 NAT 网关流入互联网。
    • 在 VPC 中添加 Amazon S3 VPC 终端节点 并更新路由表。流量将通过该网关而不是 Internet 网关流动。

    【讨论】:

    • 如何找出lambda函数的ENI?
    • @RafafTahsin 您通常不需要了解 ENI。它由 Lambda 自动创建,也可以自动删除。如果同一个 Lambda 函数横向扩展至多个容器,则可以使用多个 ENI。
    • 其实我很好奇你提到的选项2。我试图将弹性 IP 与我的 lambda 函数的 ENI 相关联。但是如何?特别是当我不知道 eni 时:|
    • 啊!我现在不推荐该选项。它可以工作,但是当添加/删除其他 ENI 时它将停止工作。如果您想尝试一下,可以查看 EC2 控制台中的 Network Interfaces 并找出哪个是由 Lambda 创建的。
    • 最后一个为我工作,按照此处的说明进行操作:stackoverflow.com/a/57742313/1327815
    【解决方案3】:

    谢谢大家!我找到了原因。

    我的 Lambda 有两个子网,private_sn_1 和 private_sn_2,

    private_sn_1 已正确设置 vpc 端点路由表,

    但是 private_sn_2 设置了错误的路由表,

    我的 ec2 在 private_sn_1 中创建,因此它可以访问 vpc 端点。

    在正常情况下,Lambda 会在 private_sn_1 或 private_sn_2 中随机运行,

    但在我的情况下,它总是在 private_sn_2 中运行(我不知道为什么),

    所以当我修复 private_sn_2 路由表时,

    一切正常。

    【讨论】:

      【解决方案4】:

      除了上述所有内容之外,VPC 端点策略也可能是禁止性的,不允许进出 S3 的流量。确保使用“完全访问”策略允许流量通过端点。

      编辑:这是相关的文档:

      您的策略必须包含一个 Principal 元素。对于网关端点 只是,您不能将委托人限制为特定的 IAM 角色或用户。 指定“*”以向所有 IAM 角色和用户授予访问权限。此外, 仅适用于网关端点,如果您以格式指定主体 "AWS":"AWS-account-ID" 或 "AWS":"arn:aws:iam::AWS-account-ID:root", 访问权限仅授予 AWS 账户根用户,而不是所有 IAM 帐户的用户和角色。

      因此,要使 S3 端点正常工作,您需要在一般情况下将“*”指定为主体

      【讨论】:

        猜你喜欢
        • 2020-05-01
        • 2017-02-08
        • 2021-07-06
        • 2019-08-12
        • 2020-02-07
        • 2017-02-18
        • 2019-10-21
        • 2020-05-21
        • 2019-06-04
        相关资源
        最近更新 更多