Dev/DevOps, Infra

[AWS] SQS event - Lambda - Slack 알람 - PostgresQL 쿼리 실행 1) Serverless framework를 사용해서 local에서 개발하고 cli로 쉽게 배포하기(aws-nodejs-typescript사용)

HJChung 2022. 5. 7. 14:58

origin SQS로 들어온 task(message)를 정상적으로 처리하지 못할 경우 그 횟수가 maxReceiveCount를 초과하게 되면 Dead-letter queue로 옮겨진다. 

 

dead-letter queue로 옮겨진 메시지에 대해서는 slack 등 개발자가 상황을 바로 알 수 있도록 alert를 보내고, 또 유저에게도 해당 task의 처리가 실패하였을 때 나타나는 데이터를 보여주는 것이 필요할 때가 있다. 

 

그래서 

SQS(dead-letter queue) event 발생시 Lambda를 사용해서 Slack alert를 보내고 PostgresQL에 쿼리를 실행하도록 설정하는 방법을 아래 3가지 순서로 기록해보고자 한다. 

  1. AWS Lambda를 Serverless framework를 사용해서 local에서 개발하고 cli로 쉽게 배포하기
  2. AWS Lambda에서 slack alert 보내기
  3. AWS Lambda에서 PostgresDB로 쿼리 실행하기

완성시 전체적인 구조는 다음과 같으며 aws credential은 미리 되어있다고 가정한다. 

 

이번에는 <1. AWS Lambda를 Serverless framework를 사용해서 local에서 개발하고 cli로 쉽게 배포하기>에 대한 내용이다. 

AWS Lambda를 사용할 경우 아래 사진처럼 console에서 직접 개발할 수 도 있다.

출처: https://rtfm.co.ua/en/aws-lambda-copy-ec2-tags-to-its-ebs-part-2-create-a-lambda-function/

하지만 간단한 몇 줄짜리 작업이면 이렇게 하면 되겠지만

코드 양이 많아지거나 복잡하고 반복적인 수동 설정등이 많거나 편한 로컬 vscode에서 개발하고 싶다면 Serverless Framework를 사용하면 된다. 

1. serverless 설치

$ npm i serverless -g

2. 프로젝트 생성

serverless 커맨드는 줄여서 sls로 사용할 수 있으며 사용 가능한 명령어들은

serverless --help로 확인해보면 된다. 

 

프로젝트 생성을 위해서는 create 명령어와 옵션들을 사용할 수 있다. 

생성시 template를 제공하는 여러 서비스들을 확인할 수 있는데,  나의 경우 aws-nodejs-typescript를 사용하였다. 

$ sls create --help

$ sls create --template aws-nodejs-typescript --path dlq-sqs-handler

그러면 성공적으로 project가 생성되었다는 말과 함께 폴더가 생성된다.

✔ Project successfully created in "dlq-sqs-handler" from "aws-nodejs-typescript" template (2s)

 

해당 폴더에 들어가 node 개발을 위한 초기 환경과 필요한 plugin 등을 설치한다. 

$ cd dlq-sqs-handler
$ npm init
$ sls plugin install -n serverless-webpack serverless-prune-plugin # 배포할 때 과거 버전의 lambda 함수를 최신 n개만 남기고 삭제해 주는 Plugin.

 

일단 여기까지 되었다면 SQS Event를 trigger로 했을 때 sample로 자동으로 생성된 hello 함수가 잘 실행되는지 aws lambda에 배포해보자. 

3. IAM role 설정

Lambda에서 SQS 서비스를 사용할 수 있도록 

IAM -> Role -> Add permissions -> AmazonSQSFullAccess, AWSLambdaBasicExecutionRole 를 부여한 역할을 만든다. 

4. 배포될 region, 만든 role 등 Lambda에 설정 내용 추가

sls create시 생성된 serverless.ts는 Lambda에 사용할 여러 리소스를 명시해주는 파일이다. 

여기에 배포할 region과 위에서 만든 role의 arn을 명시해준다. 

// serverless.ts

service: 'dlq-sqs-handler',
frameworkVersion: '2',
plugins: ['serverless-webpack', 'serverless-prune-plugin'],
provider: {
    name: 'aws',
    runtime: 'nodejs14.x',
    region: 'us-west-2',
    role: [생성한 Role의 arn],
........
어쩌구
저쩌구

※ template로 aws-nodejs를 사용하면 serverless.yml YAML 파일이 생성되고, aws-nodejs-typescript를 사용하면 serverless.ts 파일이 생성된다.  serverless.yml 작성 방법은 Serverless.yml Reference에 잘 나와있지만  serverless.ts 작성 방법은 검색해도 잘 나오지 않는다. 하지만 yml을 참고하면서 작성해보면 크게 다르지는 않는 것 같다.. 

5. 테스트를 위해 SQS Event 생성 및 테스트

SQS(dead-letter queue) event 발생 시 Lambda가 Trigger 되어 동작하도록 개발할 때 로컬에서 테스트할 때는 SQS trigger를 설정할 수가 없다. 그래서 SQS event message 형식을 맞춘 dummy event를 만들어 두고 trigger 되었다고 가정하고 테스트를 해야 한다. 

SQS event message 형식을 맞춘 dummy event는 

AWS Lambda console -> Test -> Template 에서 SQS -> body에 실제 서비스에서 들어가는 예시 넣기 

로 생성할 수 있다. 

이렇게 해서 나온 Event JSON을 project root 디렉토리에 test/sqsSample.json을 만들어 복사해 넣어준다. 

// dlq-sqs-handler/test/sqsSample.json
{
    "Records": [
        {
            "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
            "receiptHandle": "MessageReceiptHandle",
            "body": {"Message":"This is new task."}, // SQS message는 body에 담겨서 전달되므로 여길 서비스에 맞게 수정하기. 
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1523232000000",
                "SenderId": "123456789012",
                "ApproximateFirstReceiveTimestamp": "1523232000001"
            },
            "messageAttributes": {},
            "md5OfBody": "{{{md5_of_body}}}",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue",
            "awsRegion": "us-east-1"
        }
    ]
}

그리고 test를 해보려면

# $ sls invoke local -f [src/function 이름] -p [test/test json 파일명]
$ sls invoke local -f hello -p test/sqsSample.json

명령어를 입력하면 된다. 

6. Lambda에 배포

테스트시 문제없이 예상대로 동작한다면 Lambda에 배포해보자.

$ sls deploy

그러면 cloudformation -> Stacks에 내가 배포할 function name이 Stack name에 뜨고, 배포 완료가 되었으면 Status에 UPDATE_COMPLETE가 뜨면서 Lambda에서도 성공적으로 확인할 수 있다.

 

lambda의 serverless.ts(serverless.yml)과 cloudformation의 동작 방식에 대해서는

를 참고할 수 있다.

 

Reference

Amazon Simple Queue Service with NodeJs (Amazon SQS)

aws lambda 개발하기(8) - Asynchronous Tasks by SQS(Simple Queue Service)