Amazon VPC ベースの AWS Lambda 関数で接続の問題が発生し、エラーが発生します。これを解決するにはどうすれば良いですか?
簡単な説明
リモートエンドポイントまたはサービスをターゲティングし、Amazon Virtual Private Cloud (Amazon VPC) Lambda 関数を実行しようとすると、接続関連のエラーが表示されます。これは、エラーメッセージを作成するネットワーク接続の問題が原因である可能性があります。例えば、DynamoDB テーブルを作成しようとしましたが、操作がタイムアウトしたとします。
解決方法
テストするターゲット関数のネットワーク設定をレプリケートしたテスト関数を作成します。これは、ターゲット関数を編集してトラブルシューティングロジックを追加できない場合に役立ちます。VPC アクセス用に Lambda を設定する方法の詳細については、「VPC 内のリソースにアクセスするように Lambda 関数を設定する」を参照してください。
以下は、定義済みのテスト関数の例です。
import socket
def connect_tcp(event, context):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(8)
hostname = "www.amazon.com"
port = 443
server_address = (hostname, port) # Server address and port
try:
IPAddr = socket.gethostbyname(hostname)
print("Hostname: " + hostname)
print("Host IP:" + IPAddr)
print("Attempting to connect ..")
sock.connect(server_address)
sock.shutdown(socket.SHUT_RDWR)
print("connected")
except Exception as e:
print("-- Error --")
print(e)
finally:
sock.close()
この例では、ソケットタイムアウトは 8 秒に設定されており、その時間内に接続を確立しない場合には、接続は失敗するようになっています。この値は必要に応じて調整できます。
ソケットライブラリは、デフォルトでは Python ランタイムにバンドルされていない、ランタイム依存のライブラリです。これをデプロイパッケージの一部として、または関数に関連付けられたレイヤーに含めます。zip アーカイブを使用して依存関係をデプロイする方法については、「.zip ファイルアーカイブで Python Lambda 関数をデプロイする」を参照してください。依存関係をレイヤーとしてデプロイする方法については、「Lambda 関数でのレイヤーの使用」を参照してください。
注: ターゲット関数のランタイムをレプリケートするのがベストプラクティスです。テスト関数は Python で記述されていますが、他のランタイムに移植できます。
テスト関数を設定したら、次の手順に従ってトラブルシューティングを行います:
- ホスト名とポート変数を、ターゲット関数が接続を確立しようとしているものと一致するように設定します。
- ターゲット関数のネットワーク設定 (サブネットとセキュリティグループ) をミラーリングします。
- オーバーヘッドに対応するように関数のタイムアウト値を設定します。接続を可能にするために、関数のタイムアウトがソケット接続タイムアウトよりも長いことを確認するのがベストプラクティスです。
- テストを実行します。
テストが失敗した場合、接続に関する問題がある可能性があるため、調査が必要です。テストが成功した場合、Lambda Amazon VPC 環境 (セキュリティグループを含む) とエンドポイントが接続されている可能性があります。この場合、ターゲット関数とその依存関係に問題がある可能性があります。
注: 異なるルーティングプロファイルを持つ複数のサブネットが関与する場合、失敗したターゲット関数と同様のサブネットでテスト関数が起動されていることを確認するのがベストプラクティスです。
障害が発生したサブネットが不明な場合は、次の手順に従ってサブネットをローテーションし、問題のあるサブネットを特定します:
- 最初のサブネットを指定し、可用性に関する警告は無視してください。これを本番稼働用プラットフォームにデプロイすることはないからです。
- 関数をテストします。
- 次のサブネットを指定して、もう一度テストします。
- すべてのサブネットが確認できるまで、前の手順を繰り返します。