経緯
最近開発に携わっていたとある地図システムにて、以下のような構成で実行される処理がありました。
バックグラウンドでLambda(処理A)を定期実行し、そのLambdaから別のLambda(処理B)を呼び出す、という構成です。各LambdaはVPC内に配置されています。
Lambda間の呼び出し方法は複数考えられますが、最初は呼び出される側のLambdaのトリガーにAPI Gatewayを設定し、HTTP Request経由で呼び出す方式で実装しました。
IHttpClientFactory _clientFactory;
// Lambda関数をHTTP Request経由で呼び出す
var response = _clientFactory.CreateClient().GetAsync(
"https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/api/func_b");
開発環境で正常動作することを確認し、AWSにデプロイして動作確認をしたところ、何故か処理Bが実行されていない様子。ログを確認してみたところ、処理Aに実行した上記のLambda呼び出し処理にて、403エラーが発生しておりました。どうやら呼び出し元のLambdaには、呼び出し先のLambdaにアクセスする権限が与えられていないようです。
解決方法
VPC内でLambda間の呼び出しを有効にするには、API Gatewayに対しVPCエンドポイントを設定する必要があります。(参考URL: Amazon API Gateway でのプライベート API の作成)
プライベートなAPI Gateway を用意したり、リソースポリシーの設定などを編集する必要があったりと、設定がややこしく一筋縄ではいきませんが、これらを正しく設定することで、Lambda間呼び出しが可能になるはずです。
もっと簡単な方法
AWSサポートに問い合わせたところ、より簡単な方法を教えて頂きました。
そもそもの話、HTTP Request経由でのLambda呼び出しは、プライベートAPIを設定したりなど、API Gateway周りの設定を弄り回さないといけないので、非常に面倒です。AWS SDKに用意されているAmazonLambdaClientを利用すればよりシンプルにLambda間連携を実現できます。
using Amazon.Lambda;
AmazonLambdaClient _lambdaClient;
// 呼び出し先のLambda関数をFunctionNameで指定
var request = new Amazon.Lambda.Model.InvokeRequest() {
FunctionName = "funcB", InvocationType = InvocationType.Event
};
string payload = "※Lambda関数に渡すパラメータをJSON形式で生成";
request.Payload = payload;
var task = _lambdaClient.InvokeAsync(request);