こうこく
作 ▸
改 ▸

AWS Lambda内から他のLambda関数を同期的に呼び出すサンプル (Node.js)

ふたつのLambda関数間でパラメータをやりとりします。

Lambda関数①から「王様の耳は」と送ると、呼び出されたLambda関数②が「王様の耳はロバの耳」にして返却するサンプルを作りました。

もくじ

Lambda実行ロールに権限設定

前提として、Lambdaの実行ロールに他のLambda関数を実行する権限をつけておく必要があります。すでにLambda実行用のロールがある場合は、それに付与するのが楽です。無ければ先にLambda実行用のロールを作成しておきます。

権限が無いと、他のLambda関数を実行時に User: arn:aws:sts::999999999999:assumed-role/{実行ロール名]/invoke-lambda is not authorized to perform: lambda:InvokeFunction on resource: {呼び出し先Lambda関数のARN} みたいなエラーが出てしまいます。

権限はIAMのロール設定画面の、『インラインポリシーの追加』から行えます。

インラインポリシーの追加
インラインポリシーの追加

サービスはLambdaを選択します。

サービス
サービス

アクションは、面倒なのでここでは『すべてのLambdaアクション』を選択して、全部許可します。一回 InvokeFunction だけ付与してみたけど、うまくいかなかったからです。でも、本当は細かく設定した方がいいと思います。

アクション
アクション

リソースも『すべてのリソース』を選択して、全部許可します。ここも本当は、呼び出し可能なLambda関数だけ許可するとかした方がいいと思います。

リソース
リソース

最後に『ポリシーの確認』ボタンを押して、ポリシー名を入力して保存すれば完了です。

呼び出される側のLambda関数を作る

先に、呼び出される側のLambda関数を作っておきます。

関数名は、ここでは『lambda-to-be-invoked』にしました。ランタイムは Node.js 8.10 を選択します。実行ロールはLambda用のものなら何でもいいと思いますが、とりあえず上述の設定を行ったロールを選択します。

トリガーは何も設定しなくてOKです。コードは以下の通りとします。

lambda-to-be-invoked
'use strict';

exports.handler = async (event, context, callback) => {
	// パラメータ message に「ロバの耳」をつけて返却する
	callback(null, {
		message: event.message + 'ロバの耳'
	});
};

呼び出す側のLambda関数を作る

呼び出し側のLambda関数を作ります。

関数名は、ここでは『invoke-other-lambda』にしました。ランタイムは同様に Node.js 8.10 を選択します。実行ロールは、Lambda関数の実行権限を設定済みのロール (上述) を選択します。

こちらもトリガーは何も設定しなくてOKです。コードは以下の通りです。

invoke-other-lambda
'use strict';

const aws = require('aws-sdk');
const lambda = new aws.Lambda();

exports.handler = async (event, context, callback) => {
	// 実行パラメータを作成する
	// 呼び出される側のLambda関数に送りたい内容は、PayloadにJSON文字列で設定する
	const params = {
		FunctionName: 'lambda-to-be-invoked',
		InvocationType: 'RequestResponse',  // 同期的に実行
		Payload: JSON.stringify({
			message: '王様の耳は'
		})
	};
	
	// 呼び出される側のLambda関数を実行する
	const result = await lambda.invoke(params).promise();
	
	// 結果のPayloadにレスポンス内容がJSON文字列で入ってるので、取り出してパースする
	const body = JSON.parse(result.Payload);
	
	callback(null, body.message);
};

同期的に呼び出したい (プログラム内でレスポンスを受け取りたい) ので、InvocationType には RequestResponse を設定してます。初期値なので省略しても同様に動きますが、一応ここでは明記してみました。

呼び出される側で受け取りたいパラメータは Payload に設定します。文字列やバイナリを送れますが、文字列の場合はJSON形式でないとエラーになるようです。

公式リファレンスの invoke() は以下です。

Class: AWS.Lambda ― AWS SDK for JavaScript

実行結果

『invoke-other-lambda』をテストボタンで実行すると、以下のように結果が表示されるはずです。

実行結果
実行結果

以上。

この記事に何かあればこちらまで (非公開)