1, 개요

S3 Bucket에 새로운 파일이 올라오는 것을 Lambda 함수를 통해 모니터링하는 작업이다.


2. S3 Bucket 생성

당연히 S3 Bucket이 있어야 한다. 본 문서에서는 생략한다.


3. Lambda 함수 생성

3-1. 새로 작성 화면

  • 이름 : 함수 이름 (본인은 lambda-s3-trigger)
  • 런타임 : Node.js
  • 역할 : 선택 (사용자 지정 역할 생성을 선택하면 새 창이 열림)
  • 함수 생성하면 다음 페이지로 넘어감

3-2. 다음 화면

  • 왼쪽에서 트리거 추가에 S3 선택
  • 우측에는 Amazon CloudWatch Logs가 놓여져 있다.
  • 버킷 선택
  • 이벤트 유형 : 객체 생성됨(모두)
  • 트리거 활성화에 체크되어 있는지 확인
  • [추가] 클릭

3-3. 코드 생성

  • 위에 Lamda 함수 클릭 (본인은 lambda-s3-trigger 박스 클릭)
  • 코드 인라인 편집에 다음 내용 삽입 후 [저장]
exports.handler = (event, context, callback) => {
  var lastCreatedFile = event.Records[0].s3.object.key;
  console.log(lastCreatedFile);
};

4. 업로드 테스트

대상 Bucket의 temp 디렉토리에 다음 세 파일을 차례로 올려봄

  • sar_1.txt
  • sar_2.txt
  • sar_3.txt

5. CloudWatch 확인

  • CloudWatch > 로그 그룹에서 /aws/lambda/lambda-s3-trigger 선택
  • 로그 스트림 
A 00:50:06 START RequestId: 5f5f402d-f1b2-11e7-a6ee-956081cd3f56 Version: $LATEST
A 00:50:06 2018-01-05T00:50:06.929Z     5f5f402d-f1b2-11e7-a6ee-956081cd3f56    temp/sar_1.txt
A 00:50:06 END RequestId: 5f5f402d-f1b2-11e7-a6ee-956081cd3f56
A 00:50:06 REPORT RequestId: 5f5f402d-f1b2-11e7-a6ee-956081cd3f56       Duration: 12.27 ms      Billed Duration: 100 ms Memory Size: 128 MB     Max Memory Used: 19 MB
A 00:50:18 START RequestId: 666dbd1c-f1b2-11e7-947e-03ff07d67945 Version: $LATEST
A 00:50:18 2018-01-05T00:50:18.364Z     666dbd1c-f1b2-11e7-947e-03ff07d67945    temp/sar_2.txt
A 00:50:18 END RequestId: 666dbd1c-f1b2-11e7-947e-03ff07d67945
A 00:50:18 REPORT RequestId: 666dbd1c-f1b2-11e7-947e-03ff07d67945       Duration: 0.47 ms       Billed Duration: 100 ms Memory Size: 128 MB     Max Memory Used: 19 MB
A 00:51:27 START RequestId: 8fe9b4b5-f1b2-11e7-9007-37fd113dc65a Version: $LATEST
A 00:51:27 2018-01-05T00:51:27.998Z     8fe9b4b5-f1b2-11e7-9007-37fd113dc65a    temp/sar_3.txt
A 00:51:28 END RequestId: 8fe9b4b5-f1b2-11e7-9007-37fd113dc65a
A 00:51:28 REPORT RequestId: 8fe9b4b5-f1b2-11e7-9007-37fd113dc65a       Duration: 6.75 ms       Billed Duration: 100 ms Memory Size: 128 MB     Max Memory Used: 19 MB

6. 이메일 발송

6-1. SES 설정

본 문서에서는 생략함

6-2. Lambda 코드

var aws = require('aws-sdk');
var ses = new aws.SES({
    region: 'us-east-1'
});
const s3 = new aws.S3({
    apiVersion: '2006-03-01'
});
exports.handler = function(event, context, callback) {
    console.log("Incoming: ", event);
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const news = `Event took place in - ${bucket} -> ${key}`;
    const params = {
        Bucket: bucket,
        Key: key,
    };
    var eParams = {
        Destination: {
            ToAddresses: ["이 이메일 주소가 스팸봇으로부터 보호됩니다. 확인하려면 자바스크립트 활성화가 필요합니다."]
        },
        Message: {
            Body: {
                Text: {
                    Data: `${news}`
                }
            },
            Subject: {
                Data: "Email Notification"
            }
        },
        Source: "이 이메일 주소가 스팸봇으로부터 보호됩니다. 확인하려면 자바스크립트 활성화가 필요합니다."
    };
    console.log('===SENDING EMAIL===');
    var email = ses.sendEmail(eParams, function(err, data) {
        if (err) console.log(err);
        else {
            console.log("===EMAIL SENT===");
            // console.log(data);
            console.log("EMAIL CODE END");
            console.log('EMAIL: ', email);
            context.succeed(event);
        }
    });
};

6-3. 메일 발송 권한

Policy 생성 후 attach

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "*"
        }
    ]
}

6-4. 문제 발생

위와 같이 하였으나 다음과 같은 문제가 발생하였다.

018-01-05T09:39:34.580Z	.....	{ AccessDenied: User `arn:aws:sts::.....:assumed-role/role-s3-trigger/lambda-s3-trigger' is not authorized to perform `ses:SendEmail' on resource `arn:aws:ses:us-east-1:.....:identity/이 이메일 주소가 스팸봇으로부터 보호됩니다. 확인하려면 자바스크립트 활성화가 필요합니다.'
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/query.js:47:29)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request. (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
message: 'User `arn:aws:sts::.....:assumed-role/role-s3-trigger/lambda-s3-trigger\' is not authorized to perform `ses:SendEmail\' on resource `arn:aws:ses:us-east-1:.....:identity/이 이메일 주소가 스팸봇으로부터 보호됩니다. 확인하려면 자바스크립트 활성화가 필요합니다.\'',
code: 'AccessDenied',
time: 2018-01-05T09:39:34.580Z,
requestId: '.....',
statusCode: 403,
retryable: false,
retryDelay: 2.80149057710668 }

6-5. 원인

node.js 코드 상에 apiVersion을 2012-10-17 으로 수정한다. 일부러 위에 수정하지 않음.