| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- AWS Active Directory
- TryHackMe
- 침입 차단 시스템(IPS)
- 운영체제
- AWS 아키텍처 분석
- 리버싱
- AWS 3 Tier Architecture
- python
- network
- AWS 침해 사고 사례 분석
- IAM Federation
- programmers
- operating system
- dreamhack
- AWS IAM Role
- AWS 보안 사고 사례 모음
- C
- AWS 침해사고 사례 분석
- reversing.kr
- AWS 사고 사례 분석
- AWS
- reversing
- 드림핵
- AWS 보안 아키텍처 분석
- AWS 인프라 아키텍처
- terraform
- Amazon S3
- 네트워크
- AWS 인프라 분석
- 프로그래머스
- Today
- Total
lhywk 님의 블로그
AWS CloudWatch 본문
들어가기 전에 CloudWatch가 왜 필요할까?
AWS에서 서버를 운영한다고 생각해보자. EC2 인스턴스가 돌아가고 있는데 어느 순간 서비스가 느려지거나 에러가 발생했다. 이때 무슨 일이 일어났는지 알 수 있는 방법이 있어야 한다.
보안 관점에서도 마찬가지다. 누군가 MFA 없이 AWS 콘솔에 로그인을 시도했다. 혹은 Security Group 규칙이 몰래 바뀌었다. 이걸 실시간으로 알 수 있어야 하지 않을까?
이런 문제를 해결해주는 것이 Amazon CloudWatch다.
AWS 공식 문서에 따르면 CloudWatch는 AWS 리소스와 AWS에서 실행하는 애플리케이션을 실시간으로 모니터링하고 애플리케이션 성능, 운영 상태, 리소스 사용률에 대한 시스템 전반의 관찰성을 제공하는 서비스다.
쉽게 말하면 이렇다.
수집 -> 모니터링 -> 분석 -> 행동
1. CloudWatch 구조
CloudWatch는 크게 4가지 핵심 구성 요소로 이루어져 있다.
1. Metrics / Logs -> 데이터 수집
2. Metric Filter -> 로그를 숫자 지표로 변환 (선택)
3. Alarm -> 임계값 초과시 상태 변경
4. SNS -> Email 알림 발송
이 흐름을 하나씩 이해해보자.
2. CloudWatch Metrics
메트릭
Metrics(지표)는 시간에 따라 측정된 숫자 데이터다. EC2의 CPU 사용률, ALB에 들어온 요청 수, RDS의 DB 연결 수 등이 모두 메트릭이다.
메트릭의 기본 개념
Namespace
메트릭을 담는 컨테이너. AWS 서비스별로 고유한 네임스페이스가 있다.
- AWS/EC2: EC2 메트릭
- AWS/ApplicationELB: ALB 메트릭
- AWS/RDS: RDS 메트릭
- AWS/CloudFront: CloudFront 메트릭
- 사용자가 직접 만든 커스텀 메트릭은 별도 네임스페이스 지정
Dimension
메트릭을 세분화하는 키-값 쌍. 예를 들어 EC2 CPUUtilization 메트릭에서 InstanceId=i-12345678처럼 어떤 인스턴스의 CPU인지 구분할 때 사용한다.
Period
CloudWatch가 데이터를 수집하는 시간 단위. 기본적으로 5분마다 수집하며 세부 모니터링을 활성화하면 1분 단위로 수집한다.
EC2 기본 메트릭 vs CloudWatch Agent 메트릭
EC2는 별도 설정 없이도 기본 메트릭을 자동으로 CloudWatch로 전송한다.
| 구분 | 기본 제공 메트릭 | CloudWatch Agent 설치 후 |
| CPU | CPUUtilization | CPU 코어별 상세 지표 |
| 네트워크 | NetworkIn, NetworkOut | 연결 수, 에러 수 |
| 디스크 | DiskReadOps, DiskWriteOps | disk_used_percent (실제 사용률) |
| 메모리 | 없음 | mem_used_percent |
| 상태 | StatusCheckFailed | — |
3. CloudWatch Logs
CloudWatch Logs
AWS 공식 문서에 따르면 CloudWatch Logs를 사용하면 확장성이 뛰어난 단일 서비스에서 모든 시스템, 애플리케이션, AWS 서비스의 로그를 중앙 집중화할 수 있다.
EC2 안에 있는 /var/log/nginx/access.log나 애플리케이션이 출력하는 로그를 CloudWatch로 보내서 인스턴스가 삭제되거나 장애가 나도 로그가 보존되도록 할 수 있다.
로그의 계층 구조
Log Group (로그 그룹)
└── Log Stream (로그 스트림)
└── Log Event (로그 이벤트)
Log Group: 동일한 보존 기간, 접근 제어 설정을 공유하는 로그 스트림의 묶음. 예: /app/nginx/access
Log Stream: 단일 소스에서 오는 로그 이벤트의 흐름. 예: EC2 인스턴스 1대가 1개의 스트림.
Log Event: 실제 로그 한 줄 한 줄. 타임스탬프 + 메시지로 구성.
로그를 CloudWatch로 보내는 방법
| 소스 | 전송 방법 |
| EC2 시스템/앱 로그 | CloudWatch Agent 설치 |
| CloudTrail (AWS API 이력) | CloudTrail Trail 설정에서 CloudWatch Logs 활성화 |
| ALB Access Log | ALB 설정에서 S3로 저장 (CloudWatch 직접 연동 안 됨) |
| Lambda | 자동으로 CloudWatch Logs에 기록 |
| VPC Flow Logs | VPC 설정에서 CloudWatch Logs 지정 |
로그 보존 기간 설정
CloudWatch Logs는 기본적으로 로그를 영구 보관한다. 비용이 계속 발생하므로 보존 기간을 설정하는 것이 좋다. 1일부터 10년까지 설정 가능하다.
CloudWatch Agent - EC2 로그 수집
EC2 내부의 로그와 메모리/디스크 같은 세부 지표를 수집하려면 CloudWatch Agent를 설치해야 한다.
Agent를 설치하려면 EC2 IAM Role에 CloudWatchAgentServerPolicy 관리형 정책이 있어야 한다.
Agent 설치 명령어 (Amazon Linux 2 기준):
wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
sudo rpm -U ./amazon-cloudwatch-agent.rpm
Agent 설정은 Wizard로 쉽게 생성 가능하다:
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
Wizard가 묻는 것들
- 어떤 지표를 수집할지 (CPU, 메모리, 디스크 등)
- 어떤 로그 파일 경로를 수집할지 (예: /var/log/app/app.log)
- CloudWatch에 어느 로그 그룹으로 보낼지
4. Metric Filter
Metric Filter
CloudWatch Logs에 쌓이는 로그는 텍스트다. 그런데 알람을 설정하려면 숫자가 필요하다. 이 간극을 메우는 것이 Metric Filter다.
AWS 공식 문서의 정의는 Metric Filter를 사용하여 수집된 이벤트에서 지표 관찰을 추출하고 이를 지표의 데이터 포인트로 변환할 수 있다.
쉽게 말하면 이렇다
로그에서 이 패턴이 보이면 -> 숫자 1을 기록해라"
예를 들어 CloudTrail 로그에서 루트 계정 로그인이 발생하면 그 로그 한 줄을 카운트 1로 변환한다. 그러면 CloudWatch Alarm이 이 숫자를 보고 1 이상이면 알람을 발동할 수 있다.
Metric Filter의 구성 요소
| 구성 요소 | 설명 | 예시 |
| Filter Pattern | 로그에서 찾을 패턴 (JSON 조건) | { $.userIdentity.type = "Root" } |
| Metric Namespace | 생성할 지표의 네임스페이스 | SecurityMetrics |
| Metric Name | 지표 이름 | RootAccountLogin |
| Metric Value | 패턴 매칭 시 기록할 값 | 1 |
| Default Value | 패턴 없을 때 기록할 값 | 0 (설정 권장) |
CloudTrail 기반 Metric Filter에서 주의할 점
CloudTrail 로그는 JSON 형식이다. 그래서 Metric Filter 패턴도 JSON 필드를 참조하는 방식으로 작성한다.
// CloudTrail 로그 한 줄 예시
{
"eventVersion": "1.08",
"userIdentity": {
"type": "IAMUser",
"arn": "arn:aws:iam::123456789:user/alice"
},
"eventName": "ConsoleLogin",
"additionalEventData": {
"MFAUsed": "No"
}
}
이 로그에서 MFA 없는 로그인을 찾는 패턴
{ ($.eventName = "ConsoleLogin") && ($.additionalEventData.MFAUsed != "Yes") }
5. CloudWatch Alarm
Alarm
Alarm은 특정 메트릭이 설정한 임계값을 초과(또는 미달)했을 때 상태를 변경하고 액션을 트리거하는 장치다.
AWS 공식 문서에는 이렇게 말한다.
경보는 여러 기간에 대해 지정된 임계값과 지표 또는 표현식의 값을 비교하여 하나 이상의 작업을 수행한다.
알람의 3가지 상태
| 상태 | 의미 | 언제 |
| OK | 정상 | 메트릭이 임계값 범위 이내 |
| ALARM | 경보 | 메트릭이 임계값을 초과 |
| INSUFFICIENT_DATA | 데이터 부족 | 아직 데이터가 없거나 부족 |
알람 생성 직후에는 항상 INSUFFICIENT_DATA 상태에서 시작한다. 첫 번째 평가가 완료되면 OK 또는 ALARM으로 전환된다. 이는 정상 동작이므로 놀라지 않아도 된다.
알람의 핵심 파라미터
알람을 설정할 때 반드시 이해해야 하는 파라미터들이 있다.
Period
몇 초/분 단위로 메트릭을 평가할지. 예: 300 = 5분마다 평가.
Evaluation Periods (평가 기간 수)
몇 번의 Period를 평가할지. 예: 3이면 5분 × 3 = 최근 15분 데이터를 봄.
Datapoints to Alarm (알람 트리거 데이터 포인트)
Evaluation Periods 중 몇 번이 임계값을 초과해야 알람으로 전환할지. 예: Evaluation Periods가 3이고 Datapoints to Alarm이 2이면 -> 최근 3번 중 2번 초과 시 알람. 이를 M of N 알람이라고 한다.
왜 M of N이 필요한가?
순간적인 급증(스파이크)이 일어났다가 바로 정상으로 돌아오는 경우 1 of 1 설정이면 쓸데없는 알람이 계속 온다. 2 of 3이나 3 of 3으로 설정하면 일시적인 급증과 실제 문제를 구분할 수 있다.
Statistic (통계)
Period 안에서 수집된 데이터 포인트를 어떻게 집계할지.
- Average - 평균
- Sum - 합산 (이벤트 개수 카운팅에 사용)
- Maximum - 최댓값
- Minimum - 최솟값
Threshold (임계값)
알람이 발동하는 기준 값. 예: CPUUtilization이 80% 이상이면 알람.
알람의 액션
알람이 ALARM 상태가 되면 액션이 실행된다. 기본적인 예시는 SNS Topic -> Email이다.
- SNS Topic에 알람이 메시지를 전송
- SNS Topic에 구독된 이메일 주소로 알림 발송
- 수신된 이메일로 내용 확인 후 대응
알람이 OK로 돌아올 때도 알림을 설정
알람이 OK 상태로 복구될 때도 SNS에 알림을 보내도록 설정하는 것이 좋다. 그렇지 않으면 "아직 장애 상태인지, 이미 복구됐는지" 직접 확인해야 한다.
6. CloudTrail → CloudWatch Logs 연동
CloudWatch Logs Metric Filter를 CloudTrail 이벤트에 적용하려면 먼저 CloudTrail 로그가 CloudWatch Logs로 스트리밍되어야 한다.
연동 흐름
1. AWS API 호출 발생
2. CloudTrail이 이벤트 기록
3. S3에 저장 + CloudWatch Logs에 실시간 전송 (추가 설정 필요함)
4. CloudWatch Log Group에 로그 쌓임
5. Metric Filter가 특정 패턴 감지 -> 숫자 지표 생성
6. Alarm이 지표 감시 -> 임계값 초과 시 알람
7. SNS -> Email 발송
연동 설정 시 필요한 것
- CloudTrail Trail 생성
- Trail에서 CloudWatch Logs 활성화 -> Log Group 이름 지정
- IAM Role 생성 -> CloudTrail이 CloudWatch Logs에 쓸 수 있는 권한 (logs:CreateLogStream, logs:PutLogEvents)
글로벌 서비스 주의
IAM 같은 글로벌 서비스의 이벤트는 us-east-1 리전의 CloudTrail에 기록된다. 따라서 IAM 관련 알람을 설정할 때는 us-east-1 리전의 Log Group을 대상으로 Metric Filter를 생성해야 한다.
7. SNS - 알람과 이메일을 연결하는 파이프
Amazon SNS (Simple Notification Service)는 메시지를 여러 구독자에게 전달하는 서비스다. CloudWatch Alarm이 발동하면 SNS Topic에 메시지를 보내고 SNS Topic에 구독된 이메일 주소로 알림이 전달된다.
SNS 설정 흐름
1. SNS Topic 생성 (예: "security-alerts")
2. 이메일 주소 구독 추가
3. 구독 확인 이메일에서 Confirm 클릭 (반드시 해야 함!)
4. CloudWatch Alarm 생성 시 액션으로 이 SNS Topic 연결
실습 - CloudTrail을 CloudWatch Logs에 연동하기
전제 조건
- AWS 계정과 콘솔 접근 권한
- CloudTrail Trail이 이미 생성되어 있어야 함
Step 1: CloudTrail Trail에 CloudWatch Logs 연동 설정
- AWS 콘솔 -> CloudTrail 이동
- 왼쪽 메뉴에서 Trails 클릭
- 사용 중인 Trail 이름 클릭
- CloudWatch Logs 섹션에서 Edit 클릭
- Enabled 체크
- Log group -> 새 로그 그룹 이름 입력
- IAM Role -> New 선택 (자동으로 CloudTrail_CloudWatchLogs_Role 생성)
- 역할 이름 입력 (예: CloudTrailRoleForCloudWatchLogs_management-events)
- Save changes 클릭
이제 CloudTrail 이벤트가 CloudWatch Logs로 실시간 스트리밍된다.
Step 2: 정상 연동 확인
- CloudWatch 콘솔 -> Logs -> Log groups
- 방금 입력한 Log group 이름이 보이면 성공
- 로그 그룹을 클릭하면 Log Streams가 생성되어 있고 이벤트가 들어오는 것을 확인 가능
실습 - SNS Topic 생성 및 이메일 구독 설정
Step 1: SNS Topic 생성
- AWS 콘솔 -> SNS 이동
- 왼쪽 메뉴 Topics -> Create topic
- Type: Standard 선택
- Name: security-critical-alerts 입력
- [Create topic] 클릭
- 생성된 Topic의 ARN 복사해두기 (알람 설정 시 필요)
Step 2: 이메일 구독 추가
- 생성된 Topic 페이지에서 Create subscription 클릭
- Protocol: Email 선택
- Endpoint: 알람 받을 이메일 주소 입력
- Create subscription 클릭
- 해당 이메일로 확인 메일 발송됨 -> 반드시 Confirm subscription 클릭
실습 - Metric Filter 생성 (MFA 없이 콘솔 로그인 탐지)
이 실습은 MFA 없이 AWS 콘솔에 로그인한 경우를 탐지하는 Metric Filter와 알람을 만드는 것이다. AWS re:Post 공식 가이드를 참고했다.
Step 1: Metric Filter 생성
- CloudWatch 콘솔 -> Logs -> Log groups
- CloudTrail이 연동된 Log Group 클릭
- Metric filters 탭 -> Create metric filter 클릭
패턴 정의 페이지:
Filter pattern 입력란에 다음을 입력
{ ($.eventName = "ConsoleLogin") && ($.additionalEventData.MFAUsed != "Yes") }
패턴 테스트 (선택):
- 테스트 이벤트 데이터를 넣어서 패턴이 잘 매칭되는지 확인 가능
- Test pattern 클릭하면 Matches 개수가 나옴
Next 클릭
지표 할당 페이지에 다음 입력값을 입력
| 항목 | 입력값 |
| Filter name | ConsoleLoginWithoutMFA |
| Metric namespace | SecurityMetrics |
| Metric name | ConsoleLoginWithoutMFA |
| Metric value | 1 |
| Default value | 0 |
| Unit | Count |
Next -> Create metric filter 클릭
Step 2: 이 Metric Filter로 Alarm 생성
- Log Group의 Metric filters 탭
- 방금 만든 ConsoleLoginWithoutMFA 필터 체크박스 선택
- 상단의 Create alarm 클릭
지표 및 조건 지정:
| 항목 | 설정값 |
| Statistic | Sum |
| Period | 1분 (60초) |
| Threshold type | Static |
| 조건 | Greater than or equal to |
| Threshold value | 1 |
Next 클릭
알림 구성에 다음을 입력
| 항목 | 설정값 |
| Alarm state trigger | In alarm |
| SNS topic | 앞에서 만든 security-critical-alerts 선택 |
Next -> 알람 이름 입력 (ConsoleLoginWithoutMFA-Alarm) -> Create alarm
Step 3: 알람 테스트
AWS CLI로 알람 상태를 강제로 ALARM으로 바꿔서 이메일이 오는지 테스트할 수 있다
aws cloudwatch set-alarm-state --alarm-name "ConsoleLoginWithoutMFA-Alarm" --state-value ALARM --state-reason "테스트 목적" --region ap-northeast-2
이메일이 오면 정상. 테스트 후 다시 OK로 복구
aws cloudwatch set-alarm-state \
--alarm-name "ConsoleLoginWithoutMFA-Alarm" \
--state-value OK \
--state-reason "테스트 완료"

실습 - EC2 CPU 알람 생성
이것은 CloudTrail이 아닌 EC2 기본 메트릭을 사용하는 알람이다. Metric Filter 없이 직접 메트릭에서 알람을 생성한다.
Step 1: 알람 생성
- CloudWatch 콘솔 -> Alarms -> Create alarm
- Select metric 클릭
- EC2 -> Per-Instance Metrics 선택
- 모니터링할 인스턴스의 CPUUtilization 메트릭 체크 -> Select metric
지표 및 조건 지정에 다음을 입력
| 항목 | 설정값 |
| Statistic | Average |
| Period | 5분 |
| Threshold type | Static |
| 조건 | Greater than |
| Threshold value | 80 |
| Datapoints to Alarm | 3 out of 3 (15분 연속 80% 초과 시 알람) |
Next -> SNS Topic 연결 -> 알람 이름 입력 -> Create alarm
실습 - Security Group 변경 탐지 알람
이 알람은 Security Group 규칙이 변경될 때마다 이메일을 받는 설정이다. AWS 공식 CloudTrail 문서에서 권장하는 방식이다.
Step 1: Metric Filter 생성
CloudTrail Log Group에서 Metric Filter 생성
Filter pattern:
{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }
| Filter name | SecurityGroupEvents |
| Metric namespace | SecurityMetrics |
| Metric name | SecurityGroupChanges |
| Metric value | 1 |
| Default value | 0 |
Step 2: Alarm 생성
| Statistic | Sum |
| Period | 5분 |
| Threshold | >= 1 (1회 발생 즉시 알람) |
| Datapoints to Alarm | 1 out of 1 |
알람이 작동하지 않을 때 체크리스트
Metric Filter 기반 알람의 경우:
- CloudTrail -> CloudWatch Logs 연동이 실제로 활성화되어 있는가?
- Log Group에 새 이벤트가 들어오고 있는가? (Log Streams에서 확인)
- Filter Pattern이 실제 로그 형식과 맞는가? (패턴 테스트 기능 활용)
- 알람의 Statistic이 Sum으로 설정되어 있는가? (Count 기반이면 Sum이어야 함)
EC2 메트릭 기반 알람의 경우:
- 올바른 인스턴스 ID로 메트릭을 선택했는가?
- 알람의 Period와 실제 메트릭 수집 주기가 맞는가?
- EC2가 실행 중이지 않으면 메트릭이 안 들어와 INSUFFICIENT_DATA 상태 유지됨 (정상)
SNS 알림이 오지 않을 때:
- SNS Topic 구독에서 이메일 Confirm을 했는가?
- 알람 액션에 올바른 SNS Topic ARN이 연결되어 있는가?
- 스팸 메일함 확인
비용 정리
CloudWatch를 사용하면 비용이 발생한다.
| 항목 | 무료 티어 | 추가 비용 |
| 메트릭 (기본) | 10개 무료 | 메트릭당 $0.30/월 |
| 알람 | 10개 무료 | 알람당 $0.10/월 |
| 로그 수집 | 5GB/월 무료 | GB당 $0.50 |
| 로그 저장 | 5GB/월 무료 | GB당 $0.03/월 |
| Logs Insights 쿼리 | — | GB당 $0.005 |
정리
[보안 이벤트 발생]
예: MFA 없이 콘솔 로그인
↓
[CloudTrail이 API 이벤트 기록]
CloudTrail Log → S3 저장 + CloudWatch Logs 스트리밍
↓
[CloudWatch Logs에 로그 적재]
Log Group: /aws/cloudtrail/management-events
Log Stream: 계정ID_CloudTrail_리전명
↓
[Metric Filter가 패턴 감지]
{ $.eventName = "ConsoleLogin" && $.additionalEventData.MFAUsed != "Yes" }
감지 시 → SecurityMetrics/ConsoleLoginWithoutMFA 지표에 값 1 기록
↓
[CloudWatch Alarm이 지표 평가]
Sum >= 1이면 → ALARM 상태로 전환
↓
[SNS Topic에 메시지 전송]
Topic: security-critical-alerts
↓
[구독된 이메일로 알림 도착]
담당자가 이메일 수신 → 즉시 CloudTrail에서 상세 이벤트 확인 → 대응
CloudWatch는 단순한 모니터링 도구가 아니라 로그 -> 지표 -> 알람 ->액션으로 이어지는 자동화된 보안 탐지 파이프라인을 구성할 수 있는 강력한 서비스다.
특히 CloudTrail과의 연동은 누가 언제 무엇을 했는지 감사하고 의심스러운 행위를 실시간으로 탐지하는 핵심 수단이다. GuardDuty 같은 고급 위협 탐지 서비스 없이도 CloudWatch + CloudTrail 조합만으로 소규모 아키텍처 정도에서는 필요한 보안 가시성을 확보할 수 있다.
참고자료
https://repost.aws/ko/knowledge-center/cloudwatch-monitor-cloudtrail-events
https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html
https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html
'AWS' 카테고리의 다른 글
| KiranaPro 사고 사례 분석 (1) | 2026.04.09 |
|---|---|
| RStudio/Shiny를 AWS Fargate로 확장하는 서버리스 아키텍처 분석 (0) | 2026.04.05 |
| AWS CloudFront (0) | 2026.04.02 |
| AWS IAM Role & STS (0) | 2026.04.02 |
| AWS IAM (0) | 2026.04.02 |