본문 바로가기

AWS

CloudWatch, Lambda 를 이용한 SlackBot 만들기

미리보기

Intro

Cloudwatch를 이용해 Instance의 상태를 Monitoring 한 뒤 Slackbot으로 알림을 주는 것과 관련된 글을 보고 조금 흥미로웠는데, 이번에 동아리에서 Cloudwatch 및 기타 AWS service에 대해 간단히 다루게 되면서 SlackBot을 한 번 간단하게나마 만들어보고자했다. 근데 생각보다 인터넷 상의 자료들과 현재의 AWS 의 UI가 달라져서 좀 답답했었기에 직접 한 번 정리해본다.

간단한 작동 방식

뭘 만들거냐면 CloudWatch가 Monitoring 하고 Alarm을 발생시킬 수 있는 AWS Service가 몇 개 있는데, 이 글에선 EC2 Instance의 CPU Utilization(CPU 점유율)을 Monitoring하고 일정 퍼센트 이상을 사용 중이면 slack bot을 통해 알려주는 서비스를 만들어볼 것이다.

https://read.acloud.guru/slack-notification-with-cloudwatch-alarms-lambda-6f2cc77b463a

위의 구조를 따른다. (url은 사진 출처 및 도움 되는 내용)

  • EC2 의 Status ( 주로 CPU Utilization )를 CloudWatch로 모니터링 한 뒤 설정한 기준에 따른 Alarm 을 발생
  • Alarm 상태가 되면 SNS로 이벤트를 전달해 Email을 보내거나 SNSLambda로 요청 보냄
  • Lambda 함수가 실행됨.
  • 실행되면 SlackIncoming Webhooks 로 요청을 전달함.

자세한 작동 방식

1. Lambda 함수를 만든다.

우선은 위와 같이 간단한 Lambda Function을 만들어주자. Lambda Function이 제대로 작동하는 지만 확인하기 위함이다.

exports.handler에 대해 좀 더 알아보고 싶다면 Lambda에 대한 tutorial을 참고해보자. 이번 글에선 그냥 간단하게 사용만 해보겠다.

payload 인지 parameter인지 정확하진 않은데, 어쨌든 num 변수의 값을 10 곱한 뒤 response로 전달한다.

num의 값이 없다면 No input named num!! 을 response로 전달.

event는 내가 외부에서 전달받을 인자.

context는 잘은 모르겠지만 (https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-prog-model-context.html) 여기 나와있음. Lambda 함수에 대한 정보??인 듯하기도 하고.

callback은 이 lambda 함수가 작동을 완료하면 응답으로 실행하는 것. 인자는 error, response.

혹시 이 간단한 Tutorial 이후에 CloudWatch에서 발생시킨 Event Object를 이용하고 싶다면,

https://g6ling.github.io/2016/11/08/cloud-watch-alram-to-slack-ko/

위의 글을 참고하면 좋을 것 같다.

Lambda의 설정에서 위쪽에서 Test를 새로 만들어보자.

아까 설정한 대로 num이라는 key에 어떠한 숫자를 value로 전달해주자.

아까 num:1로 전달해주었으니 response는 그림처럼 1*10인 10이 된다! 굳굳!

2. Slack 에서 Incoming WebHooks를 활성화시킨다.

자기가 slackbot을 도입하고 싶은 workspace 에 Incoming webhooks app을 활성화 시키고 webhook url을 부여받는다.

Slack의 Webhook 설정은 딱히 AWS 랑 관련된 내용도 아니고, 별 다른 설명이 필요하진 않아서 생략한다. Slack Incoming webhooks 사용법 이라고만 쳐도잘 나온다.

3. Lambda 에서 Incoming Webhooks로 request 보내기.

1. 에서 Lambda가 잘 작동하는 것을 확인했다면, 이제 Lambda 함수에 본격적으로 기능을 추가한다.

즉 SNS에서 이벤트가 들어왔을 때 Lambda에서 Incoming Webhooks url에 {text:"Something"} 과 같은 형식으로 POST method에 Payload를 전달하는 작업을 추가한다. (Incoming Webhooks 자체가 POST 요청의 payload를 받음)

그리고나서 Lambda의 test를 통해 request 를 보내보고 slack에 "Something"과 같이 메시지가 발신되는지 확인해본다.

근데 사실 이 부분이 조금 쉽지만은 않은데,

우선 로컬에서 작업하고 그 파일들을 .zip 파일로 압축해서 올리는 식으로 진행할 것이다. lambda function 안에서 npm install을 하고 request 모듈을 install 하는 등의 작업은 할 수 없기 때문에, 필요한 것들을 통째로 업로드하는 것이다.

js 파일 이름은 index로 해야함!!!!

간단하게 Incoming Webhooks에 POST request를 보내는 코드 작성.

통째로 압축.

으악..ㅠㅜ... zip file을 업로드했더니 Test에서 오류가 나요.

- 어떤 오류라고 뜨는 지는 잘 기억 안나는데 경로가 잘못된 경우일 때가 많았다. 상위 폴더에서 압축을 한다거나 등등 lambda 내의 탐색기에서 아래와 같이 경로가 설정되어있어야 올바른 경우이다.

테스트해서 초록불이 뜨면 거의 정상적

갑자기 timeout error가 뜨는데요...?
- 아마 높은 확률로 request 작업을 추가하면 timeout eror가 뜰 것이다. Default timeout이 3초인데, 6초~10초 정도로 여유있게 늘려주자.

Incoming Webhooks를 설정했던 Slack workspace에 들어가서 확인해보자!!

성공적으로 Bot이 내게 말을 걸어주었다!!!

4. SNS 에서 create new topic과 new subscription.

을 통해 notification이 발생할 때 방금 작성한 Lambda Function으로 요청을 보내도록 한다.

우선 Topic을 생성하고 그 Topic에 대한 Subscription을 생성하는 식이다.

Topic이란 어떤 Topic의 Notification을 받을 지에 대한 카테고리 정도로 생각하면 되고.

Subscription은 해당 Topic에서 Notification이 발생했을 때 알림을 받을 Subscription들을 설정하는 곳이다. 예를 들어 Email이나 Lambda를 등록할 수 있다.

Topic을 만들었으면 Subscription을 만들어준다.

Topic ARN은 아까 만든 Topic이고, Endpoint는 아까 만든 요청이 들어오면 그것을 SlackBot에게 알려주는 Lambda 함수로 설정하면 된다.

6. Cloudwatch에서 Alarm을 생성한다.

방금 그 SNS를 ARN에서 추가하고, 원하는 Metric과 threshold를 설정한다.

주로 MetricCPU Utilization을 이용하고, threshold는 자기가 원하는 값을 설정한다.

예를 들어 CPU Utilization이 50%가 넘어가면 alarm event가 발생하는 식으로 설정가능하다.

또는 SlackBot과는 무관하지만, Instance에 대한 Scaling이나 Reboot등의 기능도 있다.

우리의 SNS에게 Notification을 전달할 Alarm을 만들자.

왼쪽 사이드바에서 Alarm을 클릭, 우측에 Create alarm 버튼 클릭.

어떤 수치에 대한 모니터링과 알람을 설정할 지 정하자

Select metric

자기 EC2 Instance에 대한 CPU Utilization을 선택한다.

이제 어떨 때 알람을 받을 지 설정해야하는데, 이 부분이 한글로 된 자료는 많이 없고, 영어로 된 자료도 UI가 조금씩 달라서 좀 헷갈린다. 약간의 뇌피셜로 적어본다.

metric name, instanceId는 건드리지 마세요!!(내가 설정했던 Metric이 입력된 것이고, EC2 Instance의 ID가 입력되어있는듯.)

Statistic은 측정치의 평균값, 최대값, 최소값 등 중에 무엇을 이용할 지 정하는 필드이다. 난 Maximum 의 경우를 기준으로하겠다.

Period는 5mins만 Free tier인 걸로 알고 있음! 이것 때문에 한 번 테스트 하려면 5분 기다려야한다...

그리고 나서 자기 취향대로 설정해주면 되는데, 우선 tutorial 수준이니까 thresholdstatic을 이용해서 간단하게 하나의 값만을 이용하도록하고, threshold value를 적으라고 하는데, 한국말로 하자면, 알람을 발생시킬 값을 적는 곳이다. 1000이 Default로 적혀있지만, CPU Utilization은 0~100%가 존재하니까 10000은 비정상적인 값임... 원하는 percentage 값으로 고쳐주자.

난 10을 입력하겠다.

Additional configuration이 좀 많이 헷갈렸는데,

Datapoints to alarm이 뭔소린지 도통 모르겠더라....

아마 m번의 관찰 중 n 번이 alram에 해당하면 alram을 울리겠다는 것이 아닐지... default는 1번 중1번, 즉 한 번이라도 alarm 상태이면 notification 발생인듯

아무튼 Additional은 tutorial 수준이니 안 건드려도 이상은 없다!

그 다음 Next!

in Alarm - 알람 상태에서 Notification을 받겠다.

그리고 아까 만든 SNS topic을 이용해서 알람을 받는다.

대충 원하는 대로 설명 적어준다.

이후 Create Alarm.을 해주면 끝!

작동시켜보자.

근데 Alarm이 작동하려면 실제로 CPU 점유율이 10퍼센트 이상이 되어야하고 5분이 지나야함...

아래의 코드를 이용해 EC2 인스턴스를 5분간 착취시켜버리자.... 미안해 나의 인스턴스야...

const request = require("request-promise-native");

async function doRequest() {
    let cnt = 0;
    while (true) {
        cnt++;
        let r = await request.get({{HOST URL 입력해주세요}})
        if (cnt % 100 == 0) {
            console.log(cnt + "th request")
                // console.log(r)
        }
    }
};
doRequest();
doRequest();
doRequest();
doRequest();
doRequest();

그럼 알아서 내 slack에 알람이 올 것이다.

전 조금 Lambda 에서 전달하는 메시지를 깜찍하게 바꿨습니다.

마치며

우선 EC2나 S3 등의 서비스에 비해 CloudWatch 및 Lambda는 신선했다. 마치 처음 AWS 를 접했을 때의 그 신선함이랄까..초심으로 돌아가는 듯한 느낌.

평소에 써보고 싶었던 Lambda도 써볼 수 있었고, 삽질하다가 굳이 쓰진 않아도 되는 API Gateway 도 한 번 간단하게 사용해 볼 수는 있었다. 그리고 주요한 내용이었던 CloudWatch 에 대해서도 좀 더 깊게 알아볼 기회가 되었던 것 같다.

그리고 생각보다 Slack bot 만드는 게 정말 정말 정말X100 쉽다. 옛날에 카톡봇 만들었을 때가 이제 막 express랑 nodejs를 배우던 때였고, 서버에 대한 개념, 네트워크에 대한 개념도 없던 시기라 카톡봇 만드는 게 훨씬 어렵게 느껴진 걸 수도 있겠지만, 카톡봇에 비해 Slack Bot은 정말정말 편하고 간단하고 쉽다! 나중에 진짜 시간이 나면 Google Dialogflow랑 연결해서 Slack bot을 만들어보는 것도 재밌을 것 같다.