AWS lambda를 이용해 RDS DB cloudwatch 알림 잔디(JANDI) 웹훅(webhook)으로 받기.
오늘 아침 일찍, AWS로 운영중인 개발용 DB가 다운이 됐었다.
모니터링을 살펴본 결과, 사용자가 없는데, 갑자기 이럴수가 있네?
그래서 이슈 발생시 JANDI 메신저로 webhook을 날리도록 만들기로 했다.
JANDI 또는 SLACK을 써도 된다.
[목차]
1. SNS(Simple Notification Service) topic 생성
2. RDS DB CloudWatch 설정
3. JANDI webhook URL발급
4. Lambda 함수 생성 및 SNS trigger
5. 테스트 & 실행
1. SNS(Simple Notification Service) topic 생성
적당한 이름으로 지정하면 된다.
2. RDS DB CloudWatch 설정
하고 싶은 설정을 맘껏 추가해주자!
3. JANDI webhook URL발급
잔디 토픽방 우측 상단에 커넥트 버튼을 클릭하자.
URL을 복사해두자.
4. Lambda 함수 생성 및 SNS trigger
Node.js 선택!
람다 코드, axios를 사용하기 위해선 로컬에서 npm install axios를 한 후 node_modules 폴더와 함께 .zip 파일로 업로드 하자.
// index.mjs
import axios from "axios";
export const handler = async (event) => {
console.log(JSON.stringify(event));
const JANDI_ENDPOINT = '잔디에서 발급한 webhook URL 입력';
const msg = JSON.parse(event["Records"][0]["Sns"]["Message"]);
let issue, issueOn;
const NewStateReason = msg["NewStateReason"];
const Dimensions = msg["Trigger"]["Dimensions"];
const MetricName = msg["Trigger"]["MetricName"];
const Threshold = msg["Trigger"]["Threshold"];
const reason = /.*datapoint \[(.*)\].*/g.exec(NewStateReason)[1];
if (MetricName == "DatabaseConnections") {
issue = "DB 연결 수 과도";
issueOn = `${Threshold} 초과 [ ${reason} ]`;
} else if (MetricName == "FreeableMemory") {
const mb = Threshold / 1000000;
issue = "사용 가능한 메모리 공간 부족";
issueOn = `${mb} MB 보다 부족 [ ${reason} ]`;
} else if (MetricName == "CPUUtilization") {
issue = "CPU 사용량 과도";
issueOn = `CPU 사용량 ${Threshold} % 초과 [ ${reason} ]`;
} else if (MetricName == "disk_used_percent") {
issue = "디스크 용량이 가득 참";
issueOn = `디스크 용량 ${Threshold} % 초과 [ ${reason} ]`;
} else {
issue = MetricName;
issueOn = `${Threshold} 초과`;
}
const InstanceId = Dimensions.filter(
(Dimension) => Dimension.name == "InstanceId"
)[0];
const DBInstanceIdentifier = Dimensions.filter(
(Dimension) => Dimension.name == "DBInstanceIdentifier"
)[0];
let instanceId, rdsName;
if (InstanceId) {
instanceId = InstanceId.value;
}
if (DBInstanceIdentifier) {
rdsName = DBInstanceIdentifier.value;
}
const name = rdsName ? rdsName : instanceId;
const message = {
"body" : "[AWS Infra Notification] TEST",
"connectColor" : "#FAC11B",
"connectInfo" : [{
"title" : "header",
"description" : "[" + name + "] 인프라 위험 탐지!",
},
{
"title": "section",
"description": "> *알림 |* " + name + " / " + issue + "\n> *기준 |* " + issueOn,
// "imageUrl": "https://link"
}]
};
try {
await axios.post(JANDI_ENDPOINT, message);
return {
status: 200,
body: JSON.stringify(
{
message: "Successfully ended",
input: event,
},
null,
2
),
};
} catch (err) {
return {
statusCode: 500,
body: "Error",
};
}
};
그리고 Lambda에 trigger 설정을 한다.
추가 된 것을 확인 할 수 있다.
5. 테스트 & 실행
아래 와 같이 정상 수신되는 것을 확인 할 수 있다.
참고자료
https://yonikim.tistory.com/53
https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-sns.html
https://dev.classmethod.jp/articles/receive-rds-event-alert-with-aws-sns-subscription-filter-policy/