본문 바로가기

AWS(Amazon Web Service)

CloudWatch Alarm을 Slack 연동하기

CloudWatch Alarm을 Slack으로 받을 수 있게 설정하는 방법입니다. Slack구성에 대해서는 별도 참고하시기 바랍니다.

여기에서는 CloudWatch를 이용해 RDS의 임계치와 이벤트에 대한 알림을 Slack으로 받을 수 있는 설정에 대해 다룹니다.

 

구성 절차

- KMS 사용 안함

- Slack 전송 테스트 방법
   curl -s -d "payload={\"text\":\"slack_test_message\"}" "SLACK_HOOK_URL"

 

1. SNS 주제 생성

   표준
   sns-cloudwatch-to-slack

SNS Topic

 

2. Lambda 함수 생성

  블루프린트 사용

  블루프린트 이름: Send CloudWatch alarm notification via SNS 선택
  함수 이름: cloudwatch-alarm-to-slack

  실행 역할: 기존 Lambda 권한을 가진 새 역할 생성(IAM생성 권한이 있어야 함)

 

Lambda


<역할 새로 생성> 아래와 같은 역할이 새로 생성됩니다.
Lambda가 이름이 cloudwatch-alarm-to-slack-role-8xxxxx이고 Amazon CloudWatch Logs에 로그를 업로드할 수 있는 권한이 포함된 실행 역할을 생성합니다.

 

함수 코드

import boto3
import json
import logging
import os

from base64 import b64decode
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError


HOOK_URL = os.environ['HookUrl']
SLACK_CHANNEL = os.environ['slackChannel']


logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    message = json.loads(event['Records'][0]['Sns']['Message'])
    logger.info("Message: " + str(message))

    print(message);
    
    if 'AlarmName' in message:                       # 임계치에 대한 알람 설정
        alarm_name = message['AlarmName']
        new_state = message['NewStateValue']
        reason = message['NewStateReason']
    
        slack_message = {
            'channel': SLACK_CHANNEL,
            'text': "%s state is now %s: %s" % (alarm_name, new_state, reason)
            }
        req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8'))
        try:
            response = urlopen(req)
            response.read()
            logger.info("Message posted to %s", slack_message['channel'])
        except HTTPError as e:
            logger.error("Request failed: %d %s", e.code, e.reason)
        except URLError as e:
            logger.error("Server connection failed: %s", e.reason)
        
    elif 'Source ID' in message:                   # RDS 이벤트 구독에 대한 알람 설정
        source_id = message['Source ID']
        event_time = message['Event Time']
        event_message = message['Event Message']
        
        slack_message = {
            'channel': SLACK_CHANNEL,
            'text': "%s: %s %s" % (source_id, event_time, event_message)
        }
        req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8'))
        try:
            response = urlopen(req)
            response.read()
            logger.info("Message posted to %s", slack_message['channel'])
        except HTTPError as e:
            logger.error("Request failed: %d %s", e.code, e.reason)
        except URLError as e:
            logger.error("Server connection failed: %s", e.reason)
    else:
        pass

 

 

환경 변수



3. 경보 생성

RDS 경보 생성

 

임계치에 대한 알람 생성 예시)

abc-db (CPU)                         5 분 내 1개의 데이터 포인트에 대한 CPUUtilization > 70
abc-db (DBConnection)          5 분 내 1개의 데이터 포인트에 대한 DatabaseConnections > 300
abc-db (FreeMemory)             5 분 내 1개의 데이터 포인트에 대한 FreeableMemory < 3,000,000,000
abc-db (FreeStorageSpace)    5 분 내 1개의 데이터 포인트에 대한 FreeStorageSpace < 10,000,000,000

 

RDS 이벤트 구독 생성 예시)

포함할 인스턴스 및 포함할 이벤트 범주를 활용해 받고자 하는 이벤트만 받을 수 있도록 설정