こんにちは!
BFT名古屋支店の佐野です。
今回は筆者がLambdaをVPC内のプライベートセグメントに配置した際、そのLambdaから他のLambdaやStepFunctionsを呼び出そうとした場合にハマったポイントと、その解決方法や仕組みについてお話しします。
はじめに
まず前提として、筆者は以下のような環境を構築し、Lambda_AからLambda_B、およびStepFunctionsのステートマシンを呼び出すようにコードを実装しました。
しかし、この状態ではStepFunctionsステートマシンはおろか、同じプライベートセグメント内にあるはずのLambda_Bを呼び出すこともできませんでした。
この時点で、Lambda_Aを配置しているプライベートセグメントにはVPCの外に行くための出口がないため、VPCの外のリソースであるStepFunctionsを呼び出すことができないのは理解ができました。
ただその一方で、Lambda_Aを配置しているセグメントと同じセグメントに配置しているLambda_BはVPC内のリソースとなるはずなのに、こちらも呼び出すことができないことが不可解でありました。
では、なぜLambda_AはStepFunctionsステートマシンやLambda_Bを呼び出すことができなかったのでしょうか。
StepFunctionsも、Lambdaも、呼び出す際は一度VPCの外に出る
実はVPC内に配置したLambdaも、別のLambdaから呼び出される際は必ずAWSのネットワークを介する必要があります。
Lambdaは作成時にElastic Network Interface(ENI)を作りますが、VPC内に置く設定をした場合は配置されたセグメントにENIを作ります。
そしてLambdaはこのENIを経由することで、インターネットを介することなくVPC内のリソースにアクセスすることができる……というのです。
つまりVPC内に配置する設定をしたLambdaでも、Lambda本体はVPCに置かれないのです。置かれるのはLambdaのENIだけ…!
(なお、ひとつのセグメントに複数のLambdaが配置されている場合、ENIはひとつだけ作成され、共用されます)
ではLambdaはどこにあるかというと、AWS内に存在しているLambda専用のVPCにあります。これはAWSが管理しているため、普段我々が意識することはありません。
当然どちらもAWS内にあるので、AWS内での通信のみに留めさせれば公的なインターネットに出すことなく疎通させることが可能です。
ですが「AWS内での通信」をする為には、当然VPCの外に出る必要があります。
だからLambdaがあるVPCへの出口がないプライベートセグメント内では、他のLambdaを呼び出すことができなかったのです。
当然、当初からVPCの中に無いStepFunctionsのステートマシンも同じ理由で呼び出すことができません。
プライベートセグメントと言えど、AWSのリソースを利用するためには専用の穴を開ける必要があるのです。例外はあんまりないようです。
ではどうすればよいか。今回の答えは明白です。
出口が無いのなら、出口を作ればよいのです。
VPCエンドポイント(Lambda用とStepFunctions用)を設置する
VPCエンドポイントとは「VPC内からAWSのサービスへプライベートに接続を行なう」ことを可能にするコンポーネントです。
Lambda、およびStepFunctionsに対応するVPCエンドポイントをプライベートセグメントに設置することで、公的なインターネットを経由することなくLambdaやStepFunctionsを呼び出すことが可能になります。
VPCエンドポイントは筆者の記事ではおなじみとなりつつある印象がありますが、それくらい多用し、うっかり忘れて引っかかるポイントなのです。
なお、VPCエンドポイントの作成の仕方は筆者の以下の記事にて詳しく紹介しています。
なおLambdaとStepFunctionsのVPCエンドポイントのサービス名は以下の通りです。 Lambdaは一目瞭然ですが、StepFunctionsは一見それとは分からないサービス名になっているため、注意が必要かもしれません。
AWSリソース名 | VPCエンドポイントでのサービス名 |
---|---|
Lambda | com.amazonaws.ap-northeast-1.lambda |
StepFunctions | com.amazonaws.ap-northeast-1.states |
ちなみにLambdaとStepFunctionsへの通信は、それぞれHTTPS(443)を使用するため、もしセグメントをネットワークACLやセキュリティグループで閉じている場合は、HTTPS通信の許可設定を行なう必要があります。
さいごに
VPC内に配置したLambda同士は一見何もせずとも接続しあえるように見えるものですが、仕様を追っていくと中々に手間が必要なものでした。
こうして蓋を開ければ、なんだそういうことかとすんなり設定できるものですので、今回書いた話が役立つことがあれば幸いです。
ただ、VPC外に設置したLambdaであれば、VPCエンドポイントを経由させる必要なく他のLambda(VPC内に配置されたものを除く)やStepFunctionsステートマシンを呼び出すことが可能なので、特に要件が無ければLambdaは基本VPC外に置くのがよいかもしれません。