未分類

AWS lambdaでハマったこと (lambdaからlambdaを呼び出す)

投稿日:

なぜlambdaからlambdaを呼び出すのか

これは、実際に同じ状況になってみると、わかりやすいと思います。

exports.handler = function(event, context) {
   非同期処理.then((param) => {
        paramを使用した処理
      結果を返す
   }
}

 

こうした処理を行う際に、非同期処理の終了を待ち、その結果から、処理をした内容を返して欲しかったのですが、lambdaでは、親プロセスが終了した時点で、子プロセスも強制的に閉じられてしまうらしく、paramが返ってくる前に処理が終わってしまっていました。

 

例えば、このコード。

通常の実行であれば、ABCが順番に出力されますが、lambdaで実行した場合には、Aしか出力されずに処理が終了してしまいます。

'use strict';

console.log('A');
setTimeout(() => {
    console.log('B');
    setTimeout(() => {
        console.log('C');
    }, 2000);
}, 1000);

 

それを解決するためにとった策が、lambdaからlambdaを呼ぶことです。

 

 

 

lambdaで関数を作成する

一緒にサンプルを作成していきましょう。

まず、呼び出される側のlambdaを作成します。

今回は、「Hello from Lambda」を出力するlambda関数を作成します。

 

まず、以下のリンクからAWSマネジメントコンソールへアクセスします。

https://aws.amazon.com/jp/console/

 

サービス一覧からLambdaを選択し、

関数メニュー から 関数の作成を押下します。

 

設定は、以下の通りです。

 

一応、文字でも書いておきます。

関数名: sample

ランタイム : Node.js 10.x

アクセス権限  実行ロール :  基本的な Lambda アクセス権限で新しいロールを作成

 

そして、右下にある「関数の作成」ボタンを押下すれば、関数が作成されます。

※ 少し時間がかかります。10~15秒くらいかな

 

最初は、以下のような設定になっていると思います。

もし、なっていない方のために貼っておきます。

exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

 

どのような出力になるか確認してみます。

右上の「テストボタン」を押下し、

テストイベント名に「test」と入力し、保存します。

保存ができたら、もう一度「テスト」ボタンを押下し、実行します。

結果は、以下の通り。

{
  "statusCode": 200,
  "body": "\"Hello from Lambda!\""
}

 

 

これで、Lambda関数の完成です。

今回は、lambdaからlambdaを呼び出すサンプルの作成が目的なので、関数の内容は編集しません。

 

lambdaからlambdaを呼び出す

まず、先ほどと同じ手順で新たにlambda関数を作成します。

関数名は、「callSample」としましょう。

関数が作成できたら、以下の内容をindex.jsに張り付けます。

const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
exports.handler = function(event, context) {
	
    const params = {
        FunctionName: 'sample',
        InvocationType: 'RequestResponse',
    };
    lambda.invoke(params, function(err, data) {
        if (err) {
            context.fail(err);
        } else {
            context.succeed(data);
        }
    });
};

 

このコードで、lambda関数であるsampleを呼び出そうとしています。

 

実行できるか試してみましょう。

テストを実行します。

"errorType": "AccessDeniedException",

 

が返されるはずです。

これは、権限が足りていないことを表しています。

もっと詳しく言うと、「callSample」のlambda関数に他のlambda関数(sample)を呼び出すための権限がないということです。

 

他のlambda関数を呼び出すための権限ロールを作成する

権限ロールを作成するにはIAMを使用します。

マネジメントコンソールからIAMと検索し、開いてみましょう。

 

左側のメニューからロールを選択し、ロールの作成を押下します。

 

 

AWSサービスを選択し、

権限を利用するサービスにLambdaを指定し、

「次のステップ:アクセス権限」を押下します。

 

 

ポリシーのフィルタからlambdaと検索し、「AWSLambdaRole」ポリシーをアタッチします。

設定出来たら、「次のステップ:タグ」を押下します。

 

タグは、今回利用しないので、「次のステップ:確認」を押下。

ロール名に「lambda_execute」と入力し、ロールの作成を押下します。

 

これで、権限ロールが作成されました。

 

権限を与え、実行してみる

先程作成したLambda関数に戻ります。

(callSample関数の方)

下へスクロールすると、実行ロールという項目があるため、

「既存のロールを使用する」を選択し、

既存のロールに「lambda_execute」を選択し、保存します。

 

もう一度、テストを実行してみましょう。

{
  "StatusCode": 200,
  "ExecutedVersion": "$LATEST",
  "Payload": "{\"statusCode\":200,\"body\":\"\\\"Hello from Lambda!\\\"\"}"
}

 

という結果が返れば、成功です。

 

もし、

Task timed out after 3.00 seconds

 

というエラーが返る方いれば、基本設定のタイムアウトを変更してみて下さい。

 

 

-未分類

Copyright© エンジニアの階段 , 2019 All Rights Reserved Powered by STINGER.