やりたいこと
- AWSにてLambda関数を2つ作成する。
- 1つ目のLambda関数が呼ばれたら、その関数内から2つ目のLambda関数を呼び出す。
- 1つ目のLambda関数は、2つ目のLambda関数から戻り値が返ってくるまでは終了しない。
Lambda関数用IAMロールとポリシー
下記のIAMロールを作成する。
AWSマネジメントコンソール、IAM設定画面にて、「ロールの作成」を押す。
「AWSサービス」ユースケース「Lambda」を選択し「次のステップ:アクセス権限」を押す。
「ポリシーの作成」を押す。
「JSON」タブを選択し、下記を実装する。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:*",
"logs:*",
"lambda:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PassedToService": "lambda.amazonaws.com"
}
}
},
{
"Effect": "Allow",
"Action": [
"logs:DescribeLogStreams",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
"Resource": "arn:aws:logs:*:*:log-group:/aws/lambda/*"
}
]
}
「次のステップ:タグ」を押す。
タグの設定は任意なので、不要ならそのまま「次のステップ:確認」を押す。
任意のポリシー名を記入する。
ここでは下記を入力する。
ポリシー名
LambdaPolicyYamatoSample210612a
説明は空欄のままで問題ない。
「ポリシーの作成」ボタンを押す。
下記の表示にて、ポリシーが作成されたことを確認する。
このポリシー「LambdaPolicyYamatoSample210612a」を、
ロールの作成画面にて割り当てる。
ポリシーのフィルタで「LambdaPolicyYamatoSample210612a」を検索して選択する。
チェックを入れて「次のステップ:タグ」を押す。
タグの追加は任意なので、不要なら「次のステップ:確認」を押す。
任意のロール名で作成する。今回は下記で作成する。ロール名を入力し「ロールの作成」ボタンを押す。
LambdaRoleYamatoSample210612a
下記の表示にて、ロールが作成されたことを確認する。
以上で、ポリシー「LambdaPolicyYamatoSample210612a」が割り当てられたロール「LambdaRoleYamatoSample210612a」が作成された。
このロールをLambda関数に適用する。
Lambda関数の作成
1つ目の関数を作成
AWSマネジメントコンソールのLambda画面にて「関数の作成」を押す。
下記の通り作成する。
- 「一から作成」を選ぶ。
- 関数名は任意。今回は
yamatoSampleLambdaFunction210612a
とする。 - ランタイムは Node.js 14.x とする。
- アクセス権限は「既存のロールを使用する」を選び、先ほど作成したロール「LambdaRoleYamatoSample210612a」を適用する。
「関数の作成」ボタンを押す。
2つ目の関数を作成
同様の手順で、2つ目の関数を作成する。
関数名は任意だが、今回は yamatoSampleLambdaFunction210612b
とする。
以上で、2つのLambda関数
- yamatoSampleLambdaFunction210612a
- yamatoSampleLambdaFunction210612b
が作成された。
各関数にログ出力処理を仕込む
それぞれの関数が起動した際、動いたことが分かるように、ログ出力をコードに埋め込む。
各関数の index.js に下記を実装する。
コードを修正したら「Deploy」ボタンを押す。
関数A yamatoSampleLambdaFunction210612a
console.log("関数A「yamatoSampleLambdaFunction210612a」が呼ばれました。");
関数B yamatoSampleLambdaFunction210612b
console.log("関数B「yamatoSampleLambdaFunction210612b」が呼ばれました。");
各関数をテスト実行してログが出力されることを確認する
関数を試しに動かしてみる。「テスト」を押す。
「新しいテストイベントの作成」で、イベントテンプレートは「hello-world」を選択する。
任意のイベント名を入力する。
ここでは yamatoTestEventA
とする。
「作成」ボタンを押す。
この状態で「テスト」ボタンを押すと、Lambda関数が実行される。
ログが出力されているかどうか確認する。
「モニタリング」タブを選び、「CloudWatchのログを表示」を押す。
ログストリームのリンクをクリックする。
詳細を確認する。ログが出力されている。
つまり、関数Aが起動すると、ログが出力される、ということが確認できた。
同様の手順で関数Bも動かして、関数Bのログも出力されることを確認する。
以上で、関数AとB、それぞれを動かして、ログが出力されることが確認できた。
関数AからBを呼び出す
関数AからBを呼び出すには、
関数Aの index.js に下記を実装する。
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
exports.handler = async (event) => {
console.log("関数A「yamatoSampleLambdaFunction210612a」が呼ばれました。");
let payload = {
"message":"関数Bへ渡したい文字列があればここに記入する。",
}
// ペイロードをStringにする。
payload = JSON.stringify(payload);
let params = {
FunctionName:"yamatoSampleLambdaFunction210612b",
InvocationType:"RequestResponse",
Payload:payload
}
let callLambda = '';
try {
// Lambda関数Bを呼び出す。
callLambda = await lambda.invoke(params).promise();
} catch (e) {
console.log("[ERROR]関数呼び出し失敗!",e)
}
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
解説
let params
の FunctionName
に、呼び出し先のLambda関数名を指定する。
payload
で呼び出し先の関数へパラメータを渡すこともできる。
動作確認
「テスト」を押して関数Aを動かし、ログが出力されることを確認する。
関数Aが起動すれば、関数Aが関数Bを呼び出すので、結果として関数Bのログも出力される。
関数Bのログを確認する。たしかに出力されている。つまり関数Aが関数Bを呼び出すことに成功している。
関数Aから関数Bへパラメータを渡して戻り値を返してもらう
関数Aから関数Bを呼び出す際、
引数を渡して、関数Bで受け取り、
何らかの処理をした結果を関数Aに戻す。
その場合、下記の実装にする。
関数A index.js
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
exports.handler = async (event) => {
console.log("関数A「yamatoSampleLambdaFunction210612a」が呼ばれました。");
let payload = {
"id": 1234,
"name": "Kenichiro-Yamato",
"message": "こんにちは。私の名前は大和賢一郎です。関数Aから渡されました。",
}
// ペイロードをStringにする。
payload = JSON.stringify(payload);
let params = {
FunctionName:"yamatoSampleLambdaFunction210612b",
InvocationType:"RequestResponse",
Payload:payload
}
let callLambda = '';
try {
// Lambda関数Bを呼び出す。
callLambda = await lambda.invoke(params).promise();
console.log("関数Bからの戻り値: " + JSON.stringify(callLambda));
} catch (e) {
console.log("[ERROR]関数呼び出し失敗!",e)
}
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
関数B index.js
exports.handler = async (event, body, context) => {
console.log("関数B「yamatoSampleLambdaFunction210612b」が呼ばれました。関数Aから次のパラメータを渡されました。");
console.log(JSON.stringify({event: event, body: body, context: context}, null, 2));
const response = {
statusCode: 200,
message: '関数Aさんへ。私は関数Bです。パラメータ受け取りました。ありがとう。',
event: event,
};
return response;
};
ログは下記の通り。パラメータの受け渡しと戻り値の返しが正常に実行されている。