Gom3rye
팀 프로젝트) Elastalert2를 위한 AWS API Gateway, Lambda, SNS 설정 본문
ElastAlert2 알림을 API Gateway와 Lambda를 통해 AWS SNS로 전송하기
이번 프로젝트에서는 온프레미스(On-premise) 환경의 ElastAlert 2에서 발생하는 알림을 AWS의 API Gateway를 통해 SNS(Simple Notification Service)로 전송하는 아키텍처를 구축한다.
핵심 아키텍처 및 장점
이 방식은 단순히 알림을 보내는 것을 넘어 다음과 같은 핵심적인 장점을 가진다.
- 보안 강화: 온프레미스 서버에 Access Key와 같은 장기 AWS 자격증명을 보관할 필요가 없어진다. 대신, 훨씬 안전한 API Key 방식으로 인증하여 자격증명 노출 위험을 원천적으로 차단한다.
- 유연성 및 확장성: API Gateway에서 요청을 가공하거나, 알림 대상을 SNS에서 Lambda 함수나 다른 AWS 서비스로 쉽게 변경할 수 있다. 이때 ElastAlert의 설정은 변경할 필요 없이 그대로 유지할 수 있어 유연한 확장이 가능하다.
- 제어 및 모니터링: API Gateway에서 직접 API 호출에 대한 로깅, 모니터링, 사용량 제어(Throttling) 등을 수행할 수 있어, 알림 시스템에 대한 가시성과 제어권을 확보할 수 있다.
이제부터 AWS 리소스를 설정하는 단계부터 시작한다.
1단계: AWS 인프라 설정
A. SNS (Simple Notification Service) 토픽 생성
가장 먼저 알림 메시지를 게시할 SNS 토픽을 생성한다.
📌 SNS(Simple Notification Service)란?
완전관리형 게시/구독(Pub/Sub) 메시징 서비스이다. '토픽'이라는 채널을 생성하고, 해당 토픽으로 메시지를 '게시'하면, 이 토픽을 '구독'하는 모든 대상(이메일, SMS, Lambda 함수 등)에게 메시지가 동시에 전송된다.
- AWS Management Console 에 로그인 후, 상단 검색창에서 SNS를 검색하여 Simple Notification Service로 이동한다.
- 왼쪽 메뉴에서 **토픽(Topics)**을 클릭하고, '토픽 생성(Create topic)' 버튼을 클릭한다.
- 토픽 세부 정보를 설정한다.
- 유형(Type): **표준(Standard)**을 선택한다. 표준 토픽은 다양한 프로토콜(HTTPS, 이메일, SMS 등)의 구독을 지원하며, 알림 목적에 가장 적합하다. FIFO 토픽은 메시지 순서가 엄격하게 보장되어야 할 때 사용한다. (예 : 이메일)
- 이름(Name): 토픽을 식별할 수 있는 고유한 이름을 입력한다. (예: elastalertToEmail)
- 나머지 설정(암호화, 액세스 정책 등)은 기본값으로 두고 '토픽 생성(Create topic)' 버튼을 클릭한다.
- 생성이 완료되면 토픽 목록에서 생성된 토픽을 확인할 수 있다. 이후 단계에서 사용해야 하므로 ARN(Amazon Resource Name) 값을 복사해 둔다.
- arn:aws:sns:ap-northeast-2:815800923450:elastalertToEmail
B. Lambda 함수 생성 및 권한 설정
다음으로 API Gateway로부터 요청을 받아 SNS로 메시지를 전달하는 Lambda 함수를 생성한다.
📌 AWS Lambda란?
서버를 프로비저닝하거나 관리할 필요 없이 코드를 실행할 수 있게 해주는 서버리스(Serverless) 컴퓨팅 서비스이다. 이벤트가 발생했을 때만 코드를 실행하고 사용한 컴퓨팅 시간에 대해서만 비용을 지불하므로 효율적이다.
- AWS Lambda 콘솔로 이동하여 '함수 생성'을 클릭한다.
- 옵션: 새로 작성
- 함수 이름: elastalertHandler (또는 원하는 이름)
- 런타임: Python 3.13 (또는 최신 버전)
- 아키텍처: x86_64 (기본값)
- 권한 섹션을 확장하고, **'기본 Lambda 권한으로 새 역할 생성'**을 선택한다. 이 설정은 Lambda 함수가 CloudWatch에 로그를 기록할 수 있는 기본 실행 역할을 자동으로 생성해준다.
- '함수 생성' 을 클릭한다.
- 함수가 생성되면 구성(Configuration) 탭 > 권한(Permissions) 메뉴로 이동하여 방금 생성된 역할 이름을 클릭한다. IAM 콘솔 화면으로 리디렉션된다.
- IAM 역할 화면에서 **'권한 추가(Add permissions)' > '정책 연결(Attach policies)'**을 클릭한다.
- sns를 검색하여 AmazonSNSFullAccess 정책을 선택하거나, 아래와 같이 SNS 발행(Publish) 권한만 가진 인라인 정책(예 : SNS_Publisher)을 직접 생성하여 연결한다. (보안을 위해 최소 권한 원칙을 따르는 것이 좋다.)
- 인라인 정책 JSON 예시:
Resource 값은 앞서 생성한 실제 SNS 토픽의 ARN으로 반드시 변경해야 한다.
- 인라인 정책 JSON 예시:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:ap-northeast-2:815800923450:elastalertToEmail"
}
]
}
7. 다시 Lambda 함수 화면으로 돌아와 코드(Code) 탭을 선택하고, lambda_function.py의 내용을 아래 코드로 모두 교체한다.
주의: 코드 내의 SNS_TOPIC_ARN 변수 값을 환경 변수에 설정해야 한다.
import json
import boto3
import os
# boto3 SNS 클라이언트 초기화
sns_client = boto3.client('sns')
# 환경 변수에서 SNS Topic ARN 가져오기
# 하드코딩보다 환경 변수 사용이 훨씬 안전하고 유연합니다.
SNS_TOPIC_ARN = os.environ.get('SNS_TOPIC_ARN')
def lambda_handler(event, context):
# API Gateway를 통해 전달된 ElastAlert2의 데이터는 'body'에 담겨 있습니다.
try:
# event['body']는 문자열이므로 json 객체로 파싱합니다.
alert_data = json.loads(event.get('body', '{}'))
# 이메일 제목과 내용 구성
rule_name = alert_data.get('rule_name', 'N/A')
subject = f"🚨 ElastAlert 알림 !!!"
# pre-formatted text로 이쁘게 만듭니다.
message = f"""
- 감지된 API : {alert_data.get('API', 'N/A')}
- 발생 시각: {alert_data.get('@timestamp', 'N/A')}
- SourceIP : {alert_data.get('sourceIP', 'N/A')}
- {alert_data.get('result', 'N/A')} 에러
"""
# SNS Topic으로 메시지 발행
response = sns_client.publish(
TopicArn=SNS_TOPIC_ARN,
Subject=subject,
Message=message
)
print("Message sent to SNS. Message ID: ", response['MessageId'])
# API Gateway에 성공 응답 반환
return {
'statusCode': 200,
'body': json.dumps({'message': 'Alert successfully sent to SNS!'})
}
except Exception as e:
print(f"Error processing alert: {e}")
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
8. 환경변수 설정
- '구성' 탭 > '환경 변수' > **'편집'**을 클릭합니다.
- **'환경 변수 추가'**를 클릭하고 아래와 같이 입력합니다.
- 키: SNS_TOPIC_ARN
- 값: 1단계에서 만든 SNS 주제의 ARN을 복사하여 붙여넣습니다. (ARN은 SNS 주제 상세 페이지에서 확인할 수 있습니다.)
- **'저장'**을 클릭합니다.
9. 코드 수정 후, 오른쪽 위의 'Deploy' 버튼을 클릭하여 변경 사항을 배포한다.
C. API Gateway 엔드포인트 생성 및 Lambda 연동
마지막으로 외부(ElastAlert)에서 HTTP 요청을 보낼 수 있는 엔드포인트를 생성하고, 이를 Lambda 함수와 연결한다.
📌 Amazon API Gateway란?
어떤 규모에서든 개발자가 API를 손쉽게 생성, 게시, 유지 관리, 모니터링 및 보안할 수 있도록 하는 완전관리형 서비스이다. 애플리케이션의 '관문' 역할을 하여 트래픽 관리, 권한 부여, 모니터링 등의 기능을 수행한다.
이제 Lambda 함수를 실행시킬 HTTP API 엔드포인트를 만듭니다.
- API Gateway 콘솔로 이동하여 'API 생성'을 클릭한다.
- HTTP API 카드 아래의 '구축' 버튼을 선택한다.
- 아래와 같이 API를 설정한다.
- API 이름: WebHookHandler (또는 원하는 이름)
- 통합(Integrations) 섹션에서 **'통합 추가(Add integration)'**를 클릭한다.
- 통합 대상: Lambda
- Lambda 함수: 위에서 생성한 elastalertHandler 함수를 선택한다.
- '다음'을 클릭하여 경로 구성 화면으로 이동하고, 아래와 같이 설정한다.
- 메서드: POST
- 리소스 경로: /elastalert
- 통합 대상: 방금 추가한 Lambda 함수가 선택되어 있는지 확인한다.
- '다음'을 두 번 클릭하고, 마지막 검토 화면에서 '생성'을 클릭한다.
- API가 생성되면 Stages 메뉴에서 **'호출 URL(Invoke URL)'**을 확인할 수 있다.
- 이 호출 URL과 위에서 설정한 리소스 경로(/elastalert)를 조합한 주소가 ElastAlert에서 알림을 보낼 최종 엔드포인트 주소가 된다.
이제 ElastAlert 의 alert 설정에서 url 항목에 이 주소를 입력하면, AWS 자격증명 없이도 안전하고 유연하게 알림을 보낼 수 있다.
'현대 오토에버 클라우드 스쿨' 카테고리의 다른 글
| 팀 프로젝트) Terraform EKS - 3개 클러스터 통합 관리 (VPC 공유) (0) | 2025.11.11 |
|---|---|
| 팀 프로젝트) Grafana를 위한 AWS API Gateway, Lambda, SNS 설정 (0) | 2025.11.11 |
| 팀 프로젝트) AWS Lambda 함수 (1) | 2025.11.11 |
| 팀 프로젝트) Kafka (0) | 2025.11.11 |
| 팀 프로젝트) Node Exporter/prom agent (0) | 2025.11.11 |
