목적 : AWS 계정에 대한 리소스의 생성, 삭제 등에 관한 모니터링 구성
Cloud trail
AWS CloudTrail은 AWS 계정의 운영 및 위험 감사, 거버넌스 및 규정 준수를 활성화하는데 도움을 주는 AWS 서비스
사용자, 역할 또는 AWS 서비스가 수행하는 작업은 Event로 기록됨
이벤트에는 AWS Management Console, AWS Command Line Interface 및 AWS SDK, API에서 수행되는 작업들이 포함
CloudTrail은 세가지 방법으로 Event를 기록한다.
- Event history : Event history는 지난 90일 간 한 AWS 리전의 관리 이벤트에 대해 보기, 검색 및 다운로드가 가능하고, 수정이 불가능한 레코드를 제공, 단일 속성을 필터링해 이벤트를 검색 - 과금 X
- CloudTrail Lake : AWS Cloud Lake는 감사 및 보안 목적으로 AWS의 사용자 및 API 활동을 캡처, 저장, 엑세스 및 분석하기 위한 관리형 데이터 레이크
행기반 JSON 형식의 기존 이벤트를 Apache ORC 형식으로 변환(ORC는 데이터 검색에 최적화된 열기반 스토리지 형식) - 보존 기간에 따라 과금형식이 다름
또한 CloudTrail Lake 이벤트 데이터 스토어와 쿼리에는 사용량에 따라 과금 발생
- Trails(추적) : Trails는 AWS 활동 기록을 캡쳐해 이러한 이벤트를 Amazon S3 버킷에 저장하고, 선택적으로 Amazon CloudWatch Logs 및 Amazon EventBridge로 이벤트를 전송
보안 모니터링 솔루션에 이벤트 입력 가능
Amazon Athena와 타사 솔루션 등으로 로그 검색 및 분석 가능
AWS Organizations를 사용해 단일 AWS 계정 또는 다중 AWS 계정 추적을 생성 - S3 스토리지 요금만 과금
CloudTrail 생성
AWS Organizations에서 조직을 생성한 경우, 해당 조직의 모든 AWS 계정에 대한 모든 이벤트를 로깅하는 _조직 트레일_ 을 생성할 수 있다.
AWS Console > CloudTrail > Trails > Create trail
생성이 완료되면 S3 스토리지 생성
AWSLogs/Account/CroudTrail/Region/Year/Month/Data/Logs 순으로 저장됨
Amazon CloudWatch Logs로 CloudTrail 로그 파일 모니터링
CloudWatch 콘솔에서 이벤트 보기
CloudWatch Logs 로그 그룹에 이벤트를 전송하도록 추적을 구성한 후 CloudWatch 콘솔에서 이벤트를 확인할 수 있다. CloudTrail은 일반적으로 API 호출 후 평균 5분 이내에 로그 그룹에 이벤트를 전달.
CloudTrail을 생성할때 CloudWatch에 LogGroup 생성
CloudWatch 콘솔에서 이벤트를 보려면
- [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)에서 CloudWatch 콘솔을 엽니다.
- 왼쪽 탐색 창에서 **로그(Logs)**, **로그 그룹(Log groups)**을 선택합니다.
- 추적에 대해 지정한 로그 그룹을 선택
- 확인하고자 하는 객체를 선택
- 추적이 로깅한 이벤트의 세부 정보를 보려면 이벤트를 선택
아래와 같이 Cloudtrail 로그를 확인 가능
Slack API와 연동
Slack IncommingWebhook을 통해 연동
slack -> 앱추가 -> IncommingWebhook -> 채널 설정 -> 이름, 아이콘 등 지정
Lambda Function
Process
- CloudTrail에서 CloudWatch로 보낸 Event를 파싱
- 지정한 Event에 대해 Slack을 통해 Noti
Lambda Function 생성
AWS Console > Lambda > Functions > Create Function
AutoScailing으로 Nodegroup의 인스턴스가 생성, 삭제 되는 경우 Event Name : RunInstances, TerminateInstances
- Author from scratch
CloudWatch Filters 생성
아래와 같이 구독 필터를 생성
AWS Console > CloudWatch > Log Groups > Cloudtrail-log > Subscription filters > Create Lambda subscription filter를 선택하고 생성한 lambda funtion을 선택
이전에 생성한 LambdaFunction을 생성하고 Log Format과 filter pattern 정의
Test pattern을 통해 검증 후 생성
유의사항 : Filter pattern은 두 개의 정규식만 사용 가능 추가적으로 정규식에 *만 정상작동?
그래서 이번 테스트에서는 Create&Run과 Delete&Terminate 두가지로 구성
filter pattern 구문 https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html)
예시 : { $.eventName = "Run*" || $.eventName = "Terminate*" }
아래와 같이 생성이 되면 lambda 이름의 Group이 CloudWatch Log Group이 생성됨
그 이후 Lambda funtion을 확인해보면 아래와 같이 연결된 걸 확인할 수 있다.
Lambda Function Code
- 이전에 생성한 SLACK_WEBHOOK_URL를 환경변수로 등록
- Slack으로 Log를 전송하는 코드 구성 (GPT를 이용해 코드 작성)
import json
import os
import requests
import base64
import gzip# Slack Webhook URL
SLACK_WEBHOOK_URL = os.environ['SLACK_WEBHOOK_URL']def lambda_handler(event, context):
cw_data = event['awslogs']['data']
compressed_payload = base64.b64decode(cw_data)
uncompressed_payload = gzip.decompress(compressed_payload) # SNS 메시지에서 CloudWatch 로그 이벤트를 파싱합니다.
eventContent = json.loads(uncompressed_payload)
messages = json.loads(eventContent['logEvents'][0]['message'])
# 필요한 정보를 추출합니다.
event_name = messages['eventName']
event_time = messages['eventTime']
event_source = messages['eventSource']
aws_region = messages['awsRegion']
if 'userName' in messages['userIdentity']:
user_name = messages['userIdentity']['userName']
else:
user_name = "알수없음" # Slack에 보낼 메시지를 생성합니다.
slack_message = {
'text': '*이벤트가 감지되었습니다* ![:확성기:](https://a.slack-edge.com/production-standard-emoji-assets/14.0/apple-medium/1f4e2.png)',
'attachments': [
{
'color': '#36A64F
',
'fields': [
{'title': '이벤트 이름', 'value': event_name, 'short': True},
{'title': '생성 시각', 'value': event_time, 'short': True},
{'title': '이벤트 소스', 'value': event_source, 'short': True},
{'title': '리전', 'value': aws_region, 'short': True},
{'title': '유저', 'value': user_name, 'short': True}
]
}
]
} # Slack webhook을 통해 메시지를 전송합니다.
response = requests.post(SLACK_WEBHOOK_URL, data=json.dumps(slack_message), headers={'Content-Type': 'application/json'}) # Slack으로부터의 응답을 로깅합니다.
print("Response from Slack: ", response.text) return {
'statusCode': 200,
'body': json.dumps('Message sent to Slack successfully!')
}
그러나 아래의 에러 발생
{ "errorMessage": "Unable to import module 'lambda_function': No module named 'requests'", "errorType": "Runtime.ImportModuleError", "requestId": "06e1d6ec-4b1a-4274-b533-57f6a4520e5e", "stackTrace": [] }
Lambda 함수용 배포 패키지 생성
python -m venv lambda-env
source lambda-env/bin/activate # Linux/macOS
lambda-env\Scripts\activate # Windows
vim lambda_function.py # 파일에 lambda Code 입력
pip install requests
cd $VIRTUAL_ENV/lib/python3.12/site-packages # Python 버전에 맞게 경로 조정
zip -r9 ${OLDPWD}/function.zip . # 모든 종속성을 zip 파일에 추가
cd $OLDPWD
zip -g function.zip lambda_function.py # Lambda 함수 파일 추가
Lambda file upload
- 해당 Lambda 함수를 선택
- **함수 코드** 섹션에서, Upload from > **.zip 파일 업로드**를 선택
- 생성한 function.zip 파일을 업로드
Test 성공
'Engineering' 카테고리의 다른 글
Cast.ai란 component 및 작동원리 (0) | 2024.05.21 |
---|---|
EKS에서 Spring APP Metric 추적 및 K6 LoadTest (0) | 2024.05.14 |
K6 load testing (0) | 2024.04.05 |
EKS Prometheus CPU & Memory DashBoard 구성 (0) | 2024.04.03 |
DevOps Research and Assessment (DORA) Metrics (0) | 2024.04.02 |