讓 Lambda 函數存取 Amazon VPC 中的資源 - AWS Lambda

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

讓 Lambda 函數存取 Amazon VPC 中的資源

使用 Amazon Virtual Private Cloud (Amazon VPC),您可以在 中建立私有網路 AWS 帳戶 以託管 資源,例如 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體、Amazon Relational Database Service (Amazon RDS) 執行個體和 Amazon ElastiCache 執行個體。可以透過包含資源的私有子網路,將函數連接至 VPC,讓 Lambda 函數存取 Amazon VPC 中託管的資源。請依照下列各節中的指示,使用 Lambda 主控台、 AWS Command Line Interface (AWS CLI) 或 將 Lambda 函數連接至 Amazon VPC AWS SAM。

注意

每個 Lambda 函數都會在 Lambda 服務擁有和管理的 VPC 內執行。這些 VPC 由 Lambda 自動維護,客戶看不到。設定您的函數以存取 Amazon VPC 中的其他 AWS 資源,不會影響函數在其中執行的 Lambda 受管 VPC。

所需的 IAM 許可

若要將 Lambda 函數連接至您 中的 Amazon VPC AWS 帳戶,Lambda 需要許可來建立和管理它用來讓您的函數存取 VPC 中的資源的網路界面。

Lambda 建立的網路介面稱為 Hyperplane Elastic Network Interfaces 或 Hyperplane ENI。若要進一步了解這些網路介面,請參閱 了解 Hyperplane Elastic Network Interfaces (ENI)

您可以將 AWS 受管政策 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

  • ec2:getSecurityGroupsForVpc

注意

Lambda 服務會使用您授予給函數執行角色的 Amazon EC2 許可,將函數連接至 VPC。不過,您也會隱含地將這些許可授予給函數的程式碼。這意味著您的函數程式碼能夠進行這些 Amazon EC2 API 呼叫。如需有關遵循安全最佳實務的建議,請參閱 安全最佳實務

將 Lambda 函數連接至 中的 Amazon VPC AWS 帳戶

AWS 帳戶 使用 Lambda 主控台、 AWS CLI 或 將函數連接至 中的 Amazon VPC AWS SAM。如果您使用 AWS CLI 或 AWS SAM,或使用 Lambda 主控台將現有函數連接至 VPC,請確定函數的執行角色具有上一節中列出的必要許可。

Lambda 函數無法透過專用執行個體租用直接連線到 VPC。若要連線到專用 VPC 中的資源,請透過預設租用將它對等連線到第二個 VPC

Lambda console
若要在建立時將函數連接至 Amazon VPC
  1. 開啟 Lambda 主控台的函數頁面,然後選擇 建立函數

  2. Basic information (基本資訊) 下,對於 Function name (函數名稱),為您的函數輸入名稱。

  3. 執行下列操作以配置函數的 VPC 設定:

    1. 展開 Advanced settings (進階設定)。

    2. 選取啟用 VPC,然後選擇要與函數連接的 VPC。

    3. (選擇性) 若要允許傳出 IPv6 流量,請選取允許雙堆疊子網路的 IPv6 流量

    4. 選擇要為其建立網路介面的子網路和安全群組。如果您選取允許雙堆疊子網路的 IPv6 流量,則所有選取的子網路均必須具有 IPv4 CIDR 區塊和 IPv6 CIDR 區塊。

      注意

      若要存取私有資源,請將您的函數連線到私有子網路。如果函數需要網際網路存取,請參閱 啟用 VPC 連線的 Lambda 函數的網際網路存取。將函數連接到公有子網路並不會提供網際網路存取或公有 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 函數的網際網路存取。將函數連接到公有子網路並不會提供網際網路存取或公有 IP 位址給該函數。

  7. 選擇儲存

AWS CLI
若要在建立時將函數連接至 Amazon VPC
  • 若要建立 Lambda 函數並將其連接至 VPC,請執行下列 CLI create-function 命令。

    aws lambda create-function --function-name my-function \ --runtime nodejs22.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
  • 若要將現有函數連接至 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 中斷開函數的連接,請使用 VPC 子網路和安全群組的空清單來執行下列 update-function-configuration CLI 命令。

    aws lambda update-function-configuration --function-name my-function \ --vpc-config SubnetIds=[],SecurityGroupIds=[]
AWS SAM
若要將函數連接至 VPC
  • 若要將 Lambda 函數連接至 Amazon VPC,請將 VpcConfig 屬性新增至函數定義,如下列範例範本所示。如需此屬性的詳細資訊,請參閱AWS CloudFormation 《 使用者指南》中的 AWS::Lambda::Function VpcConfig ( 屬性 AWS SAM VpcConfig會直接傳遞至 資源的 VpcConfig AWS CloudFormation AWS::Lambda::Function 屬性)。

    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

    如需在 中設定 VPC 的詳細資訊 AWS SAM,請參閱AWS CloudFormation 《 使用者指南》中的 AWS::EC2::VPC

連接到 VPC 時的網際網路存取

依預設,Lambda 函數可以存取公有網際網路。將函數連接至 VPC 時,它只能存取該 VPC 中可用的資源。若要讓您的函數存取網際網路,也需要設定 VPC 以存取網際網路。如需詳細資訊,請參閱 啟用 VPC 連線的 Lambda 函數的網際網路存取

IPv6 支援

您的函數可透過 IPv6 連線至雙堆疊 VPC 子網路中的資源。此選項預設為關閉。若要允許傳出 IPv6 流量,請使用主控台或者具有 create-functionupdate-function-configuration 命令的 --vpc-config Ipv6AllowedForDualStack=true 選項。

注意

若要允許 VPC 中的傳出 IPv6 流量,連線到該函數的所有子網路都必須是雙堆疊子網路。Lambda 不支援 VPC 中僅限 IPv6 子網路的傳出 IPv6 連線,或不支援未連線至 VPC 之函數的傳出 IPv6 連線。 IPv6-only

您可以更新函數程式碼來透過 IPv6 明確連線至子網路資源。下列 Python 範例開啟了通訊端,並連接到 IPv6 伺服器。

範例 — 連線至 IPv6 伺服器
def connect_to_server(event, context): server_address = event['host'] server_port = event['port'] message = event['message'] run_connect_to_server(server_address, server_port, message) def run_connect_to_server(server_address, server_port, message): sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0) try: # Send data sock.connect((server_address, int(server_port), 0, 0)) sock.sendall(message.encode()) BUFF_SIZE = 4096 data = b'' while True: segment = sock.recv(BUFF_SIZE) data += segment # Either 0 or end of data if len(segment) < BUFF_SIZE: break return data finally: sock.close()

搭配使用 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:DescribeSubnets", "ec2:DetachNetworkInterface", "ec2:AssignPrivateIpAddresses", "ec2:UnassignPrivateIpAddresses" ], "Resource": [ "*" ], "Condition": { "ArnEquals": { "lambda:SourceFunctionArn": [ "arn:aws:lambda:us-west-2:123456789012:function:my_function" ] } } } ] }

AWS 提供安全群組網路存取控制清單 (ACLs),以提高 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 Elastic Network Interfaces (ENI)

了解 Hyperplane Elastic Network Interfaces (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 就緒時,函數才會轉換為作用中狀態,這可能需要幾分鐘的時間。對於現有函數,您無法執行針對函數的其他操作,例如建立版本或更新函數的程式碼,但您可以繼續調用函數的先前版本。

在管理 ENI 生命週期的過程中,Lambda 可能會刪除並重新建立 ENIs,以平衡跨 ENIs 的網路流量,或解決 ENI 運作狀態檢查中發現的問題。此外,如果 Lambda 函數保持閒置 30 天,Lambda 會回收任何未使用的 Hyperplane ENIs,並將函數狀態設定為閒置。下一個調用嘗試將失敗,而且函數會重新進入擱置狀態,直到 Lambda 完成 Hyperplane ENI 的建立或配置為止。建議您的設計不要依賴 ENIs的持久性。

當您更新函數以移除其 VPC 組態時,Lambda 最多需要 20 分鐘才能刪除連接的 Hyperplane ENI。Lambda 只會在沒有其他函數 (或已發佈的函數版本) 使用該 Hyperplane ENI 時刪除 ENI。

Lambda 需要函數執行角色中的許可才能刪除 Hyperplane ENI。如果您在 Lambda 刪除 Hyperplane ENI 之前刪除執行角色,Lambda 將無法刪除 Hyperplane ENI。您可以手動執行刪除作業。

使用 IAM 條件金鑰進行 VPC 設定

您可以針對 VPC 設定使用 Lambda 特定條件金鑰,為您的 Lambda 函數提供額外的許可控制。例如,您可以請求組織中的所有功能都連線到 VPC。您也可以指定函數的使用者可以和不可以使用的子網路和安全性群組。

Lambda 支援 IAM 政策中的以下條件金鑰:

  • lambda:VpcIds - 允許或拒絕一個或多個 VPC。

  • lambda:SubnetIds - 允許或拒絕一個或多個子網路。

  • lambda:SecurityGroupIds - 允許或拒絕一個或多個安全群組。

Lambda API 操作 CreateFunctionUpdateFunctionConfiguration 支援這些條件金鑰。如需有關在 IAM 政策中使用條件金鑰的詳細資訊,請參閱 IAM 使用者指南中的 IAM JSON 政策元素:條件

提示

如果您的函數已經包含來自先前 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 中的資源。