LoginSignup
0
0

More than 1 year has passed since last update.

[AWS]LambdaからLambdaを呼ぶIAMロール設定とnode.js実装メモ

Posted at

やりたいこと

  • AWSにてLambda関数を2つ作成する。
  • 1つ目のLambda関数が呼ばれたら、その関数内から2つ目のLambda関数を呼び出す。
  • 1つ目のLambda関数は、2つ目のLambda関数から戻り値が返ってくるまでは終了しない。

Lambda関数用IAMロールとポリシー

下記のIAMロールを作成する。

AWSマネジメントコンソール、IAM設定画面にて、「ロールの作成」を押す。
image.png

「AWSサービス」ユースケース「Lambda」を選択し「次のステップ:アクセス権限」を押す。
image.png

image.png

「ポリシーの作成」を押す。

image.png

「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/*"
        }
    ]
}

「次のステップ:タグ」を押す。

image.png

タグの設定は任意なので、不要ならそのまま「次のステップ:確認」を押す。

image.png

任意のポリシー名を記入する。
ここでは下記を入力する。

ポリシー名
LambdaPolicyYamatoSample210612a

説明は空欄のままで問題ない。
「ポリシーの作成」ボタンを押す。

image.png

下記の表示にて、ポリシーが作成されたことを確認する。

image.png

このポリシー「LambdaPolicyYamatoSample210612a」を、
ロールの作成画面にて割り当てる。
ポリシーのフィルタで「LambdaPolicyYamatoSample210612a」を検索して選択する。
チェックを入れて「次のステップ:タグ」を押す。

image.png

image.png

タグの追加は任意なので、不要なら「次のステップ:確認」を押す。
image.png

任意のロール名で作成する。今回は下記で作成する。ロール名を入力し「ロールの作成」ボタンを押す。
LambdaRoleYamatoSample210612a

image.png

下記の表示にて、ロールが作成されたことを確認する。

image.png

以上で、ポリシー「LambdaPolicyYamatoSample210612a」が割り当てられたロール「LambdaRoleYamatoSample210612a」が作成された。
このロールをLambda関数に適用する。

Lambda関数の作成

1つ目の関数を作成

AWSマネジメントコンソールのLambda画面にて「関数の作成」を押す。

image.png

下記の通り作成する。

  • 「一から作成」を選ぶ。
  • 関数名は任意。今回は yamatoSampleLambdaFunction210612a とする。
  • ランタイムは Node.js 14.x とする。
  • アクセス権限は「既存のロールを使用する」を選び、先ほど作成したロール「LambdaRoleYamatoSample210612a」を適用する。

「関数の作成」ボタンを押す。

image.png

下記の表示で、Lambda関数が作成されたことを確認する。
image.png

2つ目の関数を作成

同様の手順で、2つ目の関数を作成する。
関数名は任意だが、今回は yamatoSampleLambdaFunction210612b とする。

image.png

以上で、2つのLambda関数

  • yamatoSampleLambdaFunction210612a
  • yamatoSampleLambdaFunction210612b

が作成された。

各関数にログ出力処理を仕込む

それぞれの関数が起動した際、動いたことが分かるように、ログ出力をコードに埋め込む。
各関数の index.js に下記を実装する。
コードを修正したら「Deploy」ボタンを押す。

関数A yamatoSampleLambdaFunction210612a

console.log("関数A「yamatoSampleLambdaFunction210612a」が呼ばれました。");

image.png

関数B yamatoSampleLambdaFunction210612b

console.log("関数B「yamatoSampleLambdaFunction210612b」が呼ばれました。");

image.png

各関数をテスト実行してログが出力されることを確認する

関数を試しに動かしてみる。「テスト」を押す。

image.png

「新しいテストイベントの作成」で、イベントテンプレートは「hello-world」を選択する。
任意のイベント名を入力する。
ここでは yamatoTestEventA とする。
「作成」ボタンを押す。

image.png

この状態で「テスト」ボタンを押すと、Lambda関数が実行される。

image.png

ログが出力されているかどうか確認する。
「モニタリング」タブを選び、「CloudWatchのログを表示」を押す。

image.png

ログストリームのリンクをクリックする。

image.png

詳細を確認する。ログが出力されている。

image.png

つまり、関数Aが起動すると、ログが出力される、ということが確認できた。
同様の手順で関数Bも動かして、関数Bのログも出力されることを確認する。

image.png

以上で、関数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 paramsFunctionName に、呼び出し先のLambda関数名を指定する。
payload で呼び出し先の関数へパラメータを渡すこともできる。

動作確認

「テスト」を押して関数Aを動かし、ログが出力されることを確認する。
関数Aが起動すれば、関数Aが関数Bを呼び出すので、結果として関数Bのログも出力される。
image.png

関数Bのログを確認する。たしかに出力されている。つまり関数Aが関数Bを呼び出すことに成功している。

image.png

関数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;
};

ログは下記の通り。パラメータの受け渡しと戻り値の返しが正常に実行されている。

関数Aのログ

image.png

関数Bのログ

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0