LoginSignup
6
3

More than 5 years have passed since last update.

Lambda (runtime Node.js 8.10) から SNS へ publish してメール送信する

Posted at

概要

CloudWatch Logs に特定文字列が含まれた場合、メール本文をカスタマイズして送信したいということがある。
Zipファイルをデプロイして Lambda から SNS へ publish してメール送信を試したので備忘録として記録しておく。

環境

  • Amazon Linux
  • node v8.15.1
  • npm v6.4.1

手順

  1. 関数をファイルとして準備する
  2. ZIP にする

    $ cd /home/ec2-user/lambda
    $ npm install aws-sdk
    $ ls -al
    total 20
    drwxrwxr-x 3 ec2-user ec2-user 4096 Mar 4 18:11 .
    drwx------ 10 ec2-user ec2-user 4096 Mar 4 18:11 ..
    -rw-rw-r— 1 ec2-user ec2-user 613 Mar 4 17:57 hello_nodejs.js
    drwxrwxr-x 17 ec2-user ec2-user 4096 Mar 4 18:11 node_modules
    -rw-rw-r— 1 ec2-user ec2-user 3420 Mar 4 18:11 package-lock.json
    
    $ npm install zlib
    npm WARN saveError ENOENT: no such file or directory, open '/home/ec2-user/lambda/package.json'
    npm WARN enoent ENOENT: no such file or directory, open '/home/ec2-user/lambda/package.json'
    npm WARN lambda No description
    npm WARN lambda No repository field.
    npm WARN lambda No README data
    npm WARN lambda No license field.
    + zlib@1.0.5
    added 1 package from 1 contributor and audited 38 packages in 0.9s
    found 0 vulnerabilities
    
    $ zip -r ../hello_nodejs.zip .
    $ zipinfo ../hello_nodejs.zip
    Archive: ../hello_nodejs.zip
    Zip file size: 5438595 bytes, number of entries: 1416
    ..snip..
    
  3. Lambda 関数作成する

    $ aws lambda create-function \
    --function-name hello_nodejs \
    --zip-file fileb:///home/ec2-user/hello_nodejs.zip \
    --role arn:aws:iam::accout_id:role/lambda_basic_execution \
    --handler hello_nodejs.handler \
    --runtime nodejs8.10
    
  4. Lambada 関数に実行ロールを設定する
    (ロールには、Lambda が SNS publish 実行できる権限を追加している前提)

    $ aws lambda add-permission \
    --function-name "hello_nodejs" \
    --statement-id "hello_nodejs" \
    --principal "logs.ap-northeast-1.amazonaws.com" \
    --action "lambda:InvokeFunction" \
    --source-arn "arn:aws:logs:ap-northeast-1:accout_id:log-group:TestLambda_NodeJS:*" \
    --source-account "accout_id"

5.サブスクリプションフィルターを作成する

    $ aws logs put-subscription-filter \
    --log-group-name TestLambda_NodeJS \
    --filter-name demo \
    --filter-pattern "" \
    --destination-arn arn:aws:lambda:ap-northeast-1:accout_id:function:hello_nodejs

    $ aws logs describe-subscription-filters —log-group-name TestLambda_NodeJS

6.ログを送信してテストしてみる。

    $ aws logs put-log-events —log-group-name TestLambda_NodeJS —log-stream-name stream1 —log-events "[{\"timestamp\":xxxxxxxxxxxxx , \"message\": \"Simple Lambda Test-1\"},
    {\"timestamp\":xxxxxxxxxxxxx , \"message\": \"Simple Lambda Test-2\"}]"

hello_nodejs.js ソースコード

hello_nodejs.js
var aws = require('aws-sdk');

var sns = new aws.SNS({
   apiVersion: '2010-03-31',
   region: 'ap-northeast-1'
});

function timer(ms, name) {
  console.log(`name: ${name} start!`)
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(name), ms)
  })
}

exports.handler = async function(event, context) {
    console.log('publish start')
    await timer(1000, publish(event, context));

    function publish(event, context) {
        sns.publish({
            Message: 'Message',
            Subject: 'Message title ' ,
            TargetArn: 'arn:aws:sns:region:accountId:topicName'
            }, function(err, data) {
                if (err) {
                    console.log(err.stack);
                    return "failed publish".err.stack;
                }

                console.log('publish sent');
                console.log(data);
        });
    }

};
6
3
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
6
3