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)、または AWS SAM を使用して Lambda 関数を Amazon VPC にアタッチするには、次のセクションの手順に従います。

注記

すべての Lambda 関数は、Lambda サービスによって所有および管理されている VPC 内で実行されます。これらの VPC は Lambda によって自動的に管理され、顧客には表示されません。Amazon VPC 内の他の AWS リソースにアクセスするように関数を設定しても、関数が内部で実行される Lambda が管理する VPC には影響しません。

必要な IAM 許可

Lambda 関数をAWS アカウント の Amazon VPC にアタッチするには、Lambda が VPC 内のリソースへのアクセスを関数に許可するために使用するネットワークインターフェイスを作成および管理するためのアクセス許可が必要です。

Lambda が作成するネットワークインターフェイスは、Hyperplane Elastic Network Interface または Hyperplane ENI と呼ばれます。これらのネットワークインターフェイスの詳細については、「Elastic Network Interface (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

注記

関数の実行ロールに付与する Amazon EC2 許可は、関数を VPC にアタッチするために Lambda サービスが使用します。ただし、これらのアクセス許可を関数のコードに暗黙的に付与することになります。これは、関数コードがこれらの Amazon EC2 API 呼び出しを実行できることを意味します。セキュリティのベストプラクティスに従うためのアドバイスについては、「セキュリティに関するベストプラクティス」を参照してください。

AWS アカウント の Amazon VPC への Lambda 関数のアタッチ

Lambda コンソール、AWS アカウント、または AWS CLI を使用して、AWS SAM の Amazon VPC に関数をアタッチします。AWS CLI または AWS SAM を使用している場合、または Lambda コンソールを使用して既存の関数を VPC にアタッチする場合は、関数の実行ロールに前のセクションに記載されている必要なアクセス許可があることを確認してください。

Lambda 関数は、ハードウェア専有インスタンスのテナンシーを使用して VPC に直接接続することはできません。専有 VPC のリソースに接続するには、デフォルトのテナンシーで 2 番目の 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 関数にインターネットアクセスを有効にする」を参照してください。関数をパブリックサブネットに接続しても、インターネットアクセスやパブリック 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. [Save] を選択します。

AWS 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

    独自のサブネットとセキュリティグループを指定し、ユースケースに応じて Ipv6AllowedForDualStacktrueまたは false に設定します。

既存の関数を 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 SAMVpcConfigプロパティは AWS CloudFormationAWS::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

    AWS SAM で VPC を設定する方法の詳細については、「AWS CloudFormation User Guide」の「AWS::EC2::VPC」を参照してください。

VPC にアタッチされたときのインターネットアクセス

デフォルトでは、Lambda 関数はインターネットにアクセスできます。関数を VPC にアタッチすると、関数でアクセスできるのは、その VPC 内で利用可能なリソースのみになります。関数にインターネットへのアクセスを許可するには、インターネットにアクセスできるように VPC を設定する必要があります。詳細については、「VPC に接続された Lambda 関数にインターネットアクセスを有効にする」を参照してください。

IPv6 サポート

関数は IPv6 経由でデュアルスタック VPC サブネット内のリソースに接続することができます。このオプションはデフォルトでオフに設定されています。アウトバウンド IPv6 トラフィックを許可するには、コンソールを使用するか、--vpc-config Ipv6AllowedForDualStack=true オプションで create-function または update-function-configuration コマンドを使用します。

注記

VPC でアウトバウンド IPv6 トラフィックを許可するには、関数に接続されているすべてのサブネットがデュアルスタックサブネットである必要があります。Lambda は、VPC 内の IPv6 専用サブネットのアウトバウンド IPv6 接続、VPC に接続されていない関数のアウトバウンド IPv6 接続、または VPC エンドポイント (AWS PrivateLink) を使用するインバウンド IPv6 接続をサポートしていません。

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()

Amazon VPC で Lambda を使用するためのベストプラクティス

Lambda VPC 設定がベストプラクティスガイドラインに準拠するには、次のセクションのアドバイスに従ってください。

セキュリティに関するベストプラクティス

Lambda 関数を VPC にアタッチするには、関数の実行ロールに複数の Amazon EC2 アクセス許可を付与する必要があります。これらのアクセス許可は、関数が VPC 内のリソースにアクセスするために使用するネットワークインターフェイスを作成するために必要です。ただし、これらのアクセス許可は関数のコードにも暗黙的に付与されます。つまり、関数コードにはこれらの Amazon EC2 API コールを行うアクセス許可が付与されます。

最小特権アクセスの原則に従うには、次の例のような拒否ポリシーを関数の実行ロールに追加します。このポリシーにより、関数が VPC に関数をアタッチするために Lambda サービスが使用する 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" ] } } } ] }

AWS は、VPC のセキュリティを強化するために、セキュリティグループアクセスコントロールリスト (ACL) を提供します。セキュリティグループは、リソースのインバウンドトラフィックとアウトバウンドトラフィックをコントロールします。ネットワーク ACL は、サブネットのインバウンドトラフィックとアウトバウンドトラフィックをコントロールします。セキュリティグループは、ほとんどのサブネットに対して十分なアクセス制御を提供します。VPC に追加のセキュリティレイヤーが必要な場合は、ネットワーク ACL を使用できます。Amazon VPC を使用する際のセキュリティのベスト プラクティスに関する一般的なガイドラインについては、「Amazon Virtual Private Cloud ユーザーガイド」の「VPC のセキュリティのベスト プラクティス」を参照してください。

パフォーマンスに関するベストプラクティス

関数を VPC にアタッチすると、Lambda は接続に使用できるネットワークリソース (Hyperplane ENI) があるかどうかを確認します。Hyperplane ENI は、セキュリティグループと VPC サブネットの特定の組み合わせに関連付けられています。VPC にすでに 1 つの関数をアタッチしている場合、別の関数をアタッチするときに同じサブネットとセキュリティグループを指定すると、Lambda はネットワークリソースを共有でき、新しい Hyperplane ENI を作成する必要がなくなります。Hyperplane ENI とそのライフサイクルの詳細については、「Elastic Network Interface (ENI) について」を参照してください。

Elastic Network Interface (ENI) について

Hyperplane ENI は、Lambda 関数と関数に接続するリソースとの間のネットワークインターフェイスとして機能するマネージドリソースです。Lambda サービスは、関数を VPC にアタッチするときに、これらの 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 関数の状態」を参照してください。

VPC 設定で IAM 条件キーを使用する

VPC 設定で Lambda 固有の条件キーを使用して、Lambda 関数に追加のアクセス許可コントロールを提供できます。例えば、組織内のすべての関数を VPC に接続するように要求できます。また、関数のユーザーに対して使用を許可または拒否するサブネットとセキュリティグループを指定することもできます。

Lambda は IAM ポリシーで次の条件キーをサポートしています。

  • lambda:VpcIds - 1 つ以上の VPC を許可または拒否します。

  • lambda:SubnetIds - 1 つ以上のサブネットを許可または拒否します。

  • lambda:SecurityGroupIds - 1 つ以上のセキュリティグループを許可または拒否します。

Lambda API オペレーションの CreateFunction および UpdateFunctionConfiguration は、これらの条件キーをサポートしています。IAMポリシーでの条件キーの使用の詳細については、IAM ユーザーガイドの「IAM JSON ポリシーエレメント: 条件」を参照してください。

ヒント

関数に以前の API リクエストの VPC 設定が既に含まれている場合は、VPC 設定なしで UpdateFunctionConfiguration リクエストを送信できます。

VPC 設定の条件キーを使用したポリシーの例

以下の例は、VPC 設定で条件キーを使用する方法を示しています。必要な制限を含むポリシーステートメントを作成したら、このポリシーステートメントをターゲットの ユーザーまたはロールに追加します。

ユーザーに対して VPC に接続された関数のみをデプロイさせる

すべてのユーザーに対して VPC に接続された関数のみをデプロイさせるには、有効な VPC ID を含まない関数の作成および更新オペレーションを拒否できます。

VPC ID は CreateFunction リクエストまたは UpdateFunctionConfiguration リクエストへの入力パラメータではないことに注意してください。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-1 および vpc-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-1 および subnet-2 へのユーザーアクセスを拒否します。

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

特定のセキュリティグループへのユーザーアクセスを拒否するには、StringEquals を使用して lambda:SecurityGroupIds 条件の値を確認します。次の例では、 sg-1 および sg-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-1 および vpc-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-1 および subnet-2 にアクセスすることをユーザーに許可します。

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

特定のセキュリティグループにアクセスすることをユーザーに許可するには、StringEquals を使用して lambda:SecurityGroupIds 条件の値を確認します。次の例では、sg-1 および sg-2 にアクセスすることをユーザーに許可します。

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

VPC チュートリアル

次のチュートリアルでは、VPC 内のリソースに Lambda 関数を接続します。