VPC Lambda から VPC Lambda を呼び出すときにハマった話

AWS

概要

今回、S3 バケットへのオブジェクトアップロードをトリガーに VPC 内の Lambda 関数 を起動する構成を組みました。
その Lambda からさらに別の VPC 内 Lambda 関数 を呼び出そうとしたのですが、なぜか タイムアウトエラー になり、呼び出しができずにハマりました。

ハマったポイント

「同じ VPC 内にある Lambda 同士だから直接通信できるはず」と思っていたのですが、実際にはそう簡単ではありませんでした。
試しに 通常Lambda → 通常Lambda を呼び出すと、成功。
セキュリティグループやルーティングを確認しても問題なし。しばらく原因がわからず詰まりました。

結論

最終的に解決の鍵となったのは VPC エンドポイント でした。
「同じ VPC 内だからエンドポイントは不要では?」と思っていましたが、念のため Lambda 用の VPC エンドポイント を作成したところ、正常に呼び出しができるようになりました。

なぜ VPC エンドポイントが必要なのか(考察)

これはあくまで私の考察ですが、ポイントは 「Lambda 関数の呼び出し API」 にあると思います。

Lambda → Lambda 呼び出しの実態

  • Lambda 関数から別の Lambda 関数を呼び出すとき、実際には AWS Lambda サービス API(lambda.amazonaws.com に対してリクエストが送られます。
  • これは 「同じ VPC 内のリソース間通信」ではなく、あくまで AWS サービス呼び出し という扱いです。
  • つまり「EC2 → S3」にアクセスするのと構造的には似ていて、S3 API を呼ぶのと同じ仕組みで Lambda API を呼んでいるわけです。

VPC に配置した Lambda のネットワーク事情

  • VPC 内に Lambda を配置すると、その ENI(Elastic Network Interface)は プライベートサブネットに置かれます。
  • プライベートサブネットからはデフォルトで インターネットに直接出られない ため、以下のいずれかが必要です:
    1. NAT Gateway / NAT インスタンスを経由してインターネットへ出る
    2. VPC エンドポイント(Interface Endpoint)を作って AWS サービス API へ出る
  • したがって「VPC 内 Lambda から Lambda API を呼ぶ場合」も、結局は 外部(AWS サービス API)に出る必要があるので、その経路を用意しないと通信できず、タイムアウトします。

じゃあなんで VPC エンドポイントが必要?

  • NAT Gateway を置けばパブリックエンドポイント経由で Lambda API を叩けますが、コストや設計上 NAT を避けたいケースも多いです。
  • そこで Lambda 用の VPC エンドポイント(Interface Endpoint, com.amazonaws.<region>.lambda)を作成すれば、プライベートネットワーク内から Lambda API に到達できます。
  • S3 用の VPC エンドポイントと同じ仕組みです。

よくある誤解

「同じ VPC 内にある Lambda 同士だから直接つながるのでは?」

実際には「直接ソケット通信できるわけではない」です。
Lambda 同士は物理的に同じ VPC にあっても、相互に直接通信する仕組みは存在せず、必ず「Lambda サービス API を叩いて起動」というプロセスが入ります。

まとめ

  • S3 トリガーで VPC 内 Lambda を起動
  • そこから別の VPC 内 Lambda を呼び出そうとしたらタイムアウト
  • Lambda 用 VPC エンドポイントを追加することで解決
  • Lambda 同士の通信も結局は「Lambda API 呼び出し」なので、エンドポイントを経由する必要がある

VPC Lambda を使うときは「エンドポイント周り」を確認するのが鉄則だと学びました。

コメント

タイトルとURLをコピーしました