授予 Lambda 函数访问 Amazon VPC 中资源的权限 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

授予 Lambda 函数访问 Amazon VPC 中资源的权限

使用 Amazon Virtual Private Cloud(Amazon VPC),您可以在自己的 Amazon Web Services 账户中创建私有网络,以用于托管 Amazon Elastic Compute Cloud(Amazon EC2)实例、Amazon Relational Database Service(Amazon RDS)实例和 Amazon ElastiCache 实例等资源。您可以通过包含相关资源的私有子网将函数附加到 VPC,从而向您的 Lambda 函数授予访问在 Amazon VPC 中托管的资源的权限。按照以下各节中的说明,通过 Lambda 控制台、Amazon Command Line Interface(Amazon CLI)或 Amazon SAM 将 Lambda 函数附加到 Amazon VPC。

注意

每个 Lambda 函数都在由 Lambda 服务拥有和管理的 VPC 内运行。这些 VPC 由 Lambda 自动维护,对客户不可见。配置您的函数以访问 Amazon VPC 中的其他 Amazon 资源,不会影响在其中运行函数的由 Lambda 托管的 VPC。

所需的 IAM 权限

要将 Lambda 函数附加到您的 Amazon Web Services 账户中的 Amazon VPC,Lambda 需要具有创建和管理网络接口的权限,以向您的函数授予访问该 VPC 中资源的权限。

Lambda 创建的网络接口被称为 Hyperplane 弹性网络接口,简称 Hyperplane ENI。要了解有关这些网络接口的更多信息,请参阅 了解 Hyperplane 弹性网络接口(ENI)

您可以通过将 Amazon 托管式策略 AWSLambdaVPCAccessExecutionRole 附加到函数的执行角色,从而向函数授予所需的权限。当您在 Lambda 控制台中创建新函数并将其附加到 VPC 时,Lambda 会自动为您添加此权限策略。

如果您希望创建自己的 IAM 权限策略,请务必添加以下所有权限:

  • ec2:CreateNetworkInterface

  • ec2:DescribeNetworkInterfaces:仅当所有资源 ("Resource": "*") 都允许执行此操作时,此操作才有效。

  • ec2:DescribeSubnets

  • ec2:DeleteNetworkInterface:如果您没有在执行角色中为 DeleteNetworkInterface 指定资源 ID,则函数可能无法访问 VPC。请指定唯一的资源 ID,或包含所有资源 ID,例如 "Resource": "arn:aws:ec2:us-west-2:123456789012:*/*"

  • ec2:AssignPrivateIpAddresses

  • ec2:UnassignPrivateIpAddresses

请注意,函数的角色需要这些权限只是为了创建网络接口,而不是调用您的函数。将函数附加到 Amazon VPC 后,即使您从函数的执行角色中移除了这些权限,您仍然可以成功调用该函数。

要将您的函数附加到 VPC,Lambda 还需要使用您的 IAM 用户角色验证网络资源。确保您的用户角色具有以下 IAM 权限:

  • ec2:DescribeSecurityGroups

  • ec2:DescribeSubnets

  • ec2:DescribeVpcs

注意

Lambda 服务使用授予函数执行角色的 Amazon EC2 权限,将函数附加到 VPC。不过,您还会隐式向函数的代码授予这些权限。这意味着函数代码能够进行这些 Amazon EC2 API 调用。有关遵循安全性最佳实践的建议,请参阅 安全最佳实操

将 Lambda 函数附加到您的 Amazon Web Services 账户 中的 Amazon VPC

通过 Lambda 控制台、Amazon CLI 或 Amazon SAM 将您的函数附加到您的 Amazon Web Services 账户中的 Amazon VPC。如果使用 Amazon CLI 或 Amazon SAM,或者使用 Lambda 控制台将现有的函数附加到 VPC,请确保函数的执行角色具有上一节中列出的必要权限。

Lambda 函数无法直接连接到具有专用实例租赁的 VPC。要连接到专用 VPC 中的资源,请使其与具有默认租赁的第二个 VPC 对等

Lambda console
在创建函数时将函数附加到 Amazon VPC
  1. 打开 Lambda 控制台的函数页面,然后选择创建函数

  2. 基本信息下的函数名称中输入函数的名称。

  3. 通过执行以下操作配置函数的 VPC 设置:

    1. 展开 Advanced settings(高级设置)。

    2. 选择启用 VPC,然后选择您希望附加该函数的 VPC。

    3. (可选)要允许出站 IPv6 流量,请选择允许双堆栈子网的 IPv6 流量

    4. 选择要为其创建网络接口的子网和安全组。如果您已选择允许双堆栈子网的 IPv6 流量,则所有选定的子网都必须具有 IPv4 CIDR 块和 IPv6 CIDR 块。

      注意

      要访问私有资源,请将函数连接到私有子网。如果函数需要互联网访问权限,请参阅为连接到 VPC 的 Lambda 函数启用互联网访问权限。将函数连接到公有子网不会授予其 Internet 访问权限或公有 IP 地址。

  4. 选择 Create function(创建函数)。

将现有函数附加到 Amazon VPC
  1. 打开 Lambda 控制台的“函数”页面,然后选择函数。

  2. 选择配置选项卡,然后选择 VPC

  3. 选择编辑

  4. VPC 下,选择要附加您的函数的 Amazon VPC。

  5. (可选)要允许出站 IPv6 流量,请选择允许双堆栈子网的 IPv6 流量

  6. 选择要为其创建网络接口的子网和安全组。如果您已选择允许双堆栈子网的 IPv6 流量,则所有选定的子网都必须具有 IPv4 CIDR 块和 IPv6 CIDR 块。

    注意

    要访问私有资源,请将函数连接到私有子网。如果函数需要互联网访问权限,请参阅为连接到 VPC 的 Lambda 函数启用互联网访问权限。将函数连接到公有子网不会授予其 Internet 访问权限或公有 IP 地址。

  7. 选择保存

Amazon CLI
在创建函数时将函数附加到 Amazon VPC
  • 要创建 Lambda 函数并将其附加到 VPC,请运行以下 CLI create-function 命令。

    aws lambda create-function --function-name my-function \ --runtime nodejs20.x --handler index.js --zip-file fileb://function.zip \ --role arn:aws:iam::123456789012:role/lambda-role \ --vpc-config Ipv6AllowedForDualStack=true,SubnetIds=subnet-071f712345678e7c8,subnet-07fd123456788a036,SecurityGroupIds=sg-085912345678492fb

    指定您自己的子网和安全组,并根据您的应用场景将 Ipv6AllowedForDualStack 设置为 truefalse

将现有函数附加到 Amazon VPC
  • 要将现有的 Lambda 函数附加到 VPC,请运行以下 CLI update-function-configuration 命令。

    aws lambda update-function-configuration --function-name my-function \ --vpc-config Ipv6AllowedForDualStack=true, SubnetIds=subnet-071f712345678e7c8,subnet-07fd123456788a036,SecurityGroupIds=sg-085912345678492fb
从 VPC 分离函数
  • 要从 VPC 分离函数,请使用空白的子网和安全组列表运行以下 update-function-configuration CLI 命令。

    aws lambda update-function-configuration --function-name my-function \ --vpc-config SubnetIds=[],SecurityGroupIds=[]
Amazon SAM
将函数附加到 VPC
  • 要将 Lambda 函数附加到 Amazon VPC,请将 VpcConfig 属性添加到函数定义中,如以下示例模板所示。有关此属性的更多信息,请参阅《Amazon CloudFormation 用户指南》中的 Amazon::Lambda::Function VpcConfig(将 Amazon SAM VpcConfig 属性直接传递给 Amazon CloudFormation AWS::Lambda::Function 资源的 VpcConfig 属性)。

    AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: MyFunction: Type: AWS::Serverless::Function Properties: CodeUri: ./lambda_function/ Handler: lambda_function.handler Runtime: python3.12 VpcConfig: SecurityGroupIds: - !Ref MySecurityGroup SubnetIds: - !Ref MySubnet1 - !Ref MySubnet2 Policies: - AWSLambdaVPCAccessExecutionRole MySecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security group for Lambda function VpcId: !Ref MyVPC MySubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MyVPC CidrBlock: 10.0.1.0/24 MySubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MyVPC CidrBlock: 10.0.2.0/24 MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16

    有关在 Amazon SAM 中配置 VPC 的更多信息,请参阅《Amazon CloudFormation 用户指南》中的 Amazon::EC2::VPC

连接到 VPC 时的互联网访问权限

默认情况下,Lambda 函数可以访问公共互联网。当您将函数附加到 VPC 时,该函数只能访问该 VPC 内可用的资源。要使您的函数能够访问互联网,您还需要将 VPC 配置为可以访问互联网。要了解更多信息,请参阅 为连接到 VPC 的 Lambda 函数启用互联网访问权限

将 Lambda 与 Amazon VPC 结合使用的最佳实践

为确保您的 Lambda VPC 配置符合最佳实践指南,请遵循以下各节中的建议。

安全最佳实操

要将您的 Lambda 函数附加到 VPC,您需要向函数的执行角色授予一些 Amazon EC2 权限。在创建函数用来访问 VPC 中资源的网络接口时将需要这些权限。不过,还会向函数的代码隐式授予这些权限。这意味着函数代码具有进行这些 Amazon EC2 API 调用的权限。

为遵循最低权限原则,请在函数的执行角色中添加与如下例类似的拒绝策略。此策略可防止您的函数调用 Lambda 服务用于将函数附加到 VPC 的 Amazon EC2 API。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": [ "ec2:CreateNetworkInterface", "ec2:DeleteNetworkInterface", "ec2:DescribeNetworkInterfaces", "ec2:DetachNetworkInterface", "ec2:AssignPrivateIpAddresses", "ec2:UnassignPrivateIpAddresses", ], "Resource": [ "*" ], "Condition": { "ArnEquals": { "lambda:SourceFunctionArn": [ "arn:aws:lambda:us-west-2:123456789012:function:my_function" ] } } } ] }

Amazon 提供了安全组网络访问控制列表(ACL)功能来增强 VPC 中的安全性。安全组可以控制您的资源的入站和出站流量,网络 ACL 可以控制您的子网的入站和出站流量。安全组为大多数子网提供足够的访问控制。如果需要为 VPC 增加额外安全保护,您可以使用网络 ACL。有关使用 Amazon VPC 时的安全最佳实践的一般指南,请参阅《Amazon Virtual Private Cloud 用户指南》中的 VPC 的安全最佳实践

性能最佳实践

当您将函数附加到 VPC 时,Lambda 会检查是否有可用来连接的可用网络资源(Hyperplane ENI)。Hyperplane ENI 与特定的安全组和 VPC 子网组合相关联。将一个函数附加到 VPC 后,如果在附加其他函数时指定相同的子网和安全组,这将意味着 Lambda 可以共享网络资源,无需创建新的 Hyperplane ENI。有关 Hyperplane ENI 及其生命周期的更多信息,请参阅 了解 Hyperplane 弹性网络接口(ENI)

了解 Hyperplane 弹性网络接口(ENI)

Hyperplane ENI 是一种托管式资源,在您的 Lambda 函数和您希望函数连接到的资源之间充当网络接口。当您将函数附加到 VPC 时,Lambda 服务会自动创建和管理这些 ENI。

Hyperplane ENI 对您并不直接可见,因此您无需对其进行配置或管理。不过,了解其工作原理有助您在将函数附加到 VPC 时了解其行为。

首次使用特定的子网和安全组组合将函数附加到 VPC 时,Lambda 将创建一个 Hyperplane ENI。您账户中使用相同子网和安全组组合的其他函数也可以使用该 ENI。Lambda 会尽可能重复使用现有的 ENI 来优化资源利用率并减少新 ENI 的创建。每个 Hyperplane ENI 最多支持 65,000 个连接/端口。如果连接数超过此限制,Lambda 会根据网络流量和并发要求自动扩展 ENI 的数量。

对于新函数,当 Lambda 创建 Hyperplane ENI 时,您的函数仍处于“待处理”状态,因此无法调用。只有在 Hyperplane ENI 准备就绪后,您的函数才会变为“活动”状态,这可能需要几分钟。对于现有函数,您无法执行以该函数为目标的其他操作(例如创建版本或更新函数的代码),但可以继续调用该函数的早期版本。

注意

如果 Lambda 函数持续 30 天保持空闲状态,Lambda 将会回收任何未使用的 Hyperplane ENI,并将函数状态设置为空闲。新调用尝试将会失败,并且函数会重新进入“待处理”状态,直到 Lambda 完成 Hyperplane ENI 创建或分配。有关 Lambda 函数状态的更多信息,请参阅 Lambda 函数状态

有关 Hyperplane ENI 生命周期的更多信息,请参阅 Lambda Hyperplane ENI

将 IAM 条件键用于 VPC 设置

您可以将特定于 Lambda 的条件键用于 VPC 设置,从而为您的 Lambda 函数提供额外的权限控制。例如,您可以要求组织中的所有函数都连接到 VPC。您还可以指定函数的用户可以使用和不能使用的子网和安全组。

Lambda 在 IAM policy 中支持以下条件键:

  • lambda:VpcIds – 允许或拒绝一个或多个 VPC。

  • lambda:SubnetIds – 允许或拒绝一个或多个子网。

  • lambda:SecurityGroupIds – 允许或拒绝一个或多个安全组。

Lambda API 操作 CreateFunctionUpdateFunctionConfiguration 支持这些条件键。有关在 IAM policy 中使用条件键的更多信息,请参阅《IAM 用户指南》中的IAM JSON policy 元素:条件

提示

如果您的函数已包含来自前一个 API 请求的 VPC 配置,则可以发送不带 VPC 配置的 UpdateFunctionConfiguration 请求。

带有用于 VPC 设置的条件键的示例策略

以下示例演示如何将条件键用于 VPC 设置。创建具有所需限制的策略语句后,为目标用户或角色附加策略语句。

确保用户仅部署与 VPC 连接的函数

要确保所有用户仅部署与 VPC 连接的函数,您可以拒绝不包含有效 VPC ID 的函数创建和更新操作。

请注意,VPC ID 不是 CreateFunctionUpdateFunctionConfiguration 请求的输入参数。Lambda 根据子网和安全组参数检索 VPC ID 值。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "EnforceVPCFunction", "Action": [ "lambda:CreateFunction", "lambda:UpdateFunctionConfiguration" ], "Effect": "Deny", "Resource": "*", "Condition": { "Null": { "lambda:VpcIds": "true" } } } ] }

拒绝用户访问特定的 VPC、子网或安全组

要拒绝用户访问特定 VPC,请使用 StringEquals 检查 lambda:VpcIds 条件的值。以下示例拒绝用户访问 vpc-1vpc-2

{ "Version": "2012-10-17", "Statement": [ { "Sid": "EnforceOutOfVPC", "Action": [ "lambda:CreateFunction", "lambda:UpdateFunctionConfiguration" ], "Effect": "Deny", "Resource": "*", "Condition": { "StringEquals": { "lambda:VpcIds": ["vpc-1", "vpc-2"] } } }

要拒绝用户访问特定子网,请使用 StringEquals 检查 lambda:SubnetIds 条件的值。以下示例拒绝用户访问 subnet-1subnet-2

{ "Sid": "EnforceOutOfSubnet", "Action": [ "lambda:CreateFunction", "lambda:UpdateFunctionConfiguration" ], "Effect": "Deny", "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "lambda:SubnetIds": ["subnet-1", "subnet-2"] } } }

要拒绝用户访问特定安全组,请使用 StringEquals 检查 lambda:SecurityGroupIds 条件的值。以下示例拒绝用户访问 sg-1sg-2

{ "Sid": "EnforceOutOfSecurityGroups", "Action": [ "lambda:CreateFunction", "lambda:UpdateFunctionConfiguration" ], "Effect": "Deny", "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "lambda:SecurityGroupIds": ["sg-1", "sg-2"] } } } ] }

允许用户使用特定 VPC 设置创建和更新函数

要允许用户访问特定的 VPC,请使用 StringEquals 检查 lambda:VpcIds 条件的值。以下示例允许用户访问 vpc-1vpc-2

{ "Version": "2012-10-17", "Statement": [ { "Sid": "EnforceStayInSpecificVpc", "Action": [ "lambda:CreateFunction", "lambda:UpdateFunctionConfiguration" ], "Effect": "Allow", "Resource": "*", "Condition": { "StringEquals": { "lambda:VpcIds": ["vpc-1", "vpc-2"] } } }

要允许用户访问特定子网,请使用 StringEquals 检查 lambda:SubnetIds 条件的值。以下示例允许用户访问 subnet-1subnet-2

{ "Sid": "EnforceStayInSpecificSubnets", "Action": [ "lambda:CreateFunction", "lambda:UpdateFunctionConfiguration" ], "Effect": "Allow", "Resource": "*", "Condition": { "ForAllValues:StringEquals": { "lambda:SubnetIds": ["subnet-1", "subnet-2"] } } }

要允许用户访问特定的安全组, 请使用 StringEquals 检查 lambda:SecurityGroupIds 条件的值。以下示例允许用户访问 sg-1sg-2

{ "Sid": "EnforceStayInSpecificSecurityGroup", "Action": [ "lambda:CreateFunction", "lambda:UpdateFunctionConfiguration" ], "Effect": "Allow", "Resource": "*", "Condition": { "ForAllValues:StringEquals": { "lambda:SecurityGroupIds": ["sg-1", "sg-2"] } } } ] }

VPC 教程

在以下教程中,您会将 Lambda 函数连接到 VPC 中的资源。