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 にピア接続します
VPC にアタッチされたときのインターネットアクセス
デフォルトでは、Lambda 関数はインターネットにアクセスできます。関数を VPC にアタッチすると、関数でアクセスできるのは、その VPC 内で利用可能なリソースのみになります。関数にインターネットへのアクセスを許可するには、インターネットにアクセスできるように VPC を設定する必要があります。詳細については、「VPC に接続された Lambda 関数にインターネットアクセスを有効にする」を参照してください。
IPv6 サポート
関数は IPv6 経由でデュアルスタック VPC サブネット内のリソースに接続することができます。このオプションはデフォルトでオフに設定されています。アウトバウンド IPv6 トラフィックを許可するには、コンソールを使用するか、--vpc-config Ipv6AllowedForDualStack=true
オプションで create-function
注記
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:DescribeSubnets", "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 関数を接続します。