きっかけ
とある案件の要件確認MTGをしているときに、
僕:「LambdaAを動かすために定期的にLambdaBを動かす構成」
👦:「LambdaBを定期実行ではなく、条件を満たしていない時だけ動かしたい」
みたいな話があり、そういやLambdaから他のLambdaを動かす方法ってどうやるのか?という疑問から
※ そもそもLambdaから他のLambdaを呼び出すことに抵抗があり、できれば定期実行を軸に進めたいのは本音。フェイルセーフ的な位置づけでロジック自体は実装することになりそうとの考察。(基本は定期実行。なんらかの問題で条件を満たさない場合があればLambda呼び出し実行。) Best Practiceに沿った内容があればコメントください。。。
前提
- AWS: 社用アカウント利用
Summary
- 呼び出す側Lambda関数で、AWS-SDKのインポート、AWS-SDK.Lambdaのインスタンス化、Lambdaインスタンスでinvoke関数の実行
- 呼び出す側Lambda関数のIAMポリシーに "lambda:InvokeFunction"を許可する設定を追加
構築Step
- 呼ばれる側Lambdaの構築、ソース修正
- 呼ぶ側Lambdaの構築、ソース修正
- 呼ぶ側Lambdaに紐づくIAMロールの修正
- 動作確認
1. 呼ばれる側Lambdaの構築、ソース修正
- AWS Lambdaのダッシュボードから'関数の作成'を押下
- 以下、添付画像の内容へ変更、'関数の作成'を押下
- 作成完了後、コードタブでソースコードを以下に修正、デプロイ
index.js
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Called Lambda!'),
};
return response;
};
2. 呼ぶ側Lambdaの構築、ソース修正
- AWS Lambdaのダッシュボードから'関数の作成'を押下
- 以下、添付画像の内容へ変更、'関数の作成'を押下
- 作成完了後、コードタブでソースコードを以下に修正、デプロイ
index.js
'use strict';
const aws = require('aws-sdk');
const lambda = new aws.Lambda();
exports.handler = async (event) => {
const params = {
FunctionName: 'test-called-function',
InvocationType: 'RequestResponse',
};
const result = await lambda.invoke(params).promise();
const response = {
statusCode: 200,
body: JSON.stringify(result),
};
return response;
};
3. 呼ぶ側Lambdaに紐づくIAMロールの修正
- test-calling-function関数の画面で設定タブ>アクセス権限>実行ロールで記載されているロール名リンクを押下
- IAMロール画面でリンクになっているポリシー名を押下(例: AWSLambdaBasicExecutionRole-XXXXXX)
- IAMポリシー画面で'ポリシーの変更'を押下
- JSONタブに切り替えて、以下のアクセス情報を追加
IAMポリシー
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": test-called-functionのARN (例:"arn:aws:lambda:ap-northeast-1:XXXXX:function:test-called-function")
}
4. 動作確認
- test-calling-function関数の画面でテストタブを選択、テンプレート名を適当に入力し、'テスト'を押下
- 実行結果: 成功、 詳細の返却値が以下のようになっていることを確認
レスポンス
{
"statusCode": 200,
"body": "{\"StatusCode\":200,\"ExecutedVersion\":\"$LATEST\",\"Payload\":\"{\\\"statusCode\\\":200,\\\"body\\\":\\\"\\\\\\\"Hello from Called Lambda!\\\\\\\"\\\"}\"}"
}
参考サイト