Skip to content

operations alerting

minsoo edited this page Jun 9, 2026 · 1 revision

Alert 운영

RiskAlertDispatcher의 Slack secret 준비, 배포, 테스트, 로그, DynamoDB 전송 상태와 실패 대응 절차를 정리한다.


보안 원칙

  • Slack webhook URL 원문을 repo, 문서, Terraform 변수, Terraform state, 명령 출력에 남기지 않는다.
  • Terraform은 Secrets Manager의 secret metadata와 Lambda가 참조할 ARN만 관리한다.
  • Secret value는 로컬 제한 파일에서 build script가 put-secret-value로 별도 주입한다.
  • Secret metadata 확인에는 describe-secret을 사용한다. 운영 점검에서 get-secret-value 출력을 남기지 않는다.

Webhook Secret 준비

Cloud와 factory-a/b/c용 webhook 파일을 각각 준비한다. 실제 경로는 환경에 맞게 정하고 문서에는 URL을 기록하지 않는다.

<secrets-root>/cloud-webhook
<secrets-root>/factory-a-webhook
<secrets-root>/factory-b-webhook
<secrets-root>/factory-c-webhook

파일에는 webhook URL 한 줄만 두고 권한을 제한한다.

chmod 600 <secrets-root>/*-webhook

Factory B/C 채널은 synthetic dummy anomaly 알림이 들어오는 테스트 채널임을 채널 설명이나 운영 공지에 표시하는 것이 좋다.


Build Script 주입

Data pipeline 전체 배포 명령:

cd merge
scripts/build/build-data-pipe.sh [MFA_OTP]

다른 secret 파일을 사용할 때는 경로만 환경 변수로 전달한다.

AEGIS_RISK_ALERT_SLACK_WEBHOOK_FILE=<secrets-root>/cloud-webhook \
AEGIS_RISK_ALERT_SLACK_WEBHOOK_FACTORY_A_FILE=<secrets-root>/factory-a-webhook \
AEGIS_RISK_ALERT_SLACK_WEBHOOK_FACTORY_B_FILE=<secrets-root>/factory-b-webhook \
AEGIS_RISK_ALERT_SLACK_WEBHOOK_FACTORY_C_FILE=<secrets-root>/factory-c-webhook \
scripts/build/build-data-pipe.sh [MFA_OTP]

Script는 다음 순서로 동작한다.

  1. infra/data-pipeline Terraform init/validate/plan/apply
  2. RiskAlertDispatcher Lambda, S3 trigger, secret metadata 배포
  3. 존재하는 로컬 webhook 파일의 값을 Secrets Manager에 주입
  4. 파일이 없으면 경고하고 apply 자체는 성공으로 유지

따라서 build 성공만으로 Slack 전송 가능 상태가 보장되지는 않는다. 각 scope secret value가 실제로 준비됐는지 metadata와 테스트 결과를 확인한다.


정적 테스트

코드 규칙과 cooldown/confirmation 로직은 다음 테스트로 확인한다.

cd merge
python -m pytest apps/risk-alert-dispatcher/tests -q
python -m pytest apps/cloud-infra-collector/tests -q

주요 검증 항목:

  • factory warning/danger와 pipeline freshness 중복 억제
  • Cloud specific 우선, generic fallback
  • warning 2회 확인 window
  • danger 및 일부 warning의 즉시 처리
  • OBSERVATION#과 cooldown item 분리
  • scope별 Slack secret routing
  • Cloud overall_status의 factory freshness 포함

배포 상태와 로그

Lambda 상태:

aws lambda get-function-configuration \
  --function-name AEGIS-Lambda-RiskAlertDispatcher \
  --query '{State:State,LastUpdateStatus:LastUpdateStatus,EnvironmentKeys:keys(Environment.Variables)}'

S3 trigger:

aws s3api get-bucket-notification-configuration \
  --bucket <data-bucket>

최근 로그:

aws logs tail /aws/lambda/AEGIS-Lambda-RiskAlertDispatcher \
  --since 30m

결과 해석:

결과 의미
sent Slack HTTP 호출 후 상태 기록 완료
awaiting_confirmation warning 첫 관측, 더 최신 snapshot 필요
cooldown_or_stale_snapshot 같은 fingerprint가 cooldown 중이거나 snapshot이 오래됨
slack_not_configured 기본 webhook 설정이 없어 dispatch 전에 skip
slack_send_failed HTTP/secret 조회 등 전송 단계 실패
unsupported_key Dispatcher 대상이 아닌 S3 key
normal 평가 결과 alert 없음

DynamoDB State 확인

Factory alert item 예:

aws dynamodb get-item \
  --table-name AEGIS-DynamoDB-FactoryStatus \
  --key '{"pk":{"S":"ALERT#factory-a"},"sk":{"S":"danger#nodes_all_not_ready#state_snapshot"}}'

Cloud warning 확인 item 예:

aws dynamodb get-item \
  --table-name AEGIS-DynamoDB-FactoryStatus \
  --key '{"pk":{"S":"ALERT#cloud-infra"},"sk":{"S":"OBSERVATION#warning#data_pipeline_lambda_errors#fast"}}'

확인할 필드:

last_source_updated_at
last_observed_at
observation_count
last_sent_at
cooldown_until
last_slack_status
last_slack_error
ttl

ALERT# partition은 장기 알림 목록이 아니다. 같은 fingerprint의 현재 dedupe 상태를 update하며 기본 7일 TTL로 만료된다.


Cooldown 조정

Terraform 기본값:

factory warning 900s
factory danger  300s
cloud warning   900s
cloud danger    300s

조정 변수:

risk_alert_factory_warning_cooldown_seconds
risk_alert_factory_danger_cooldown_seconds
risk_alert_cloud_warning_cooldown_seconds
risk_alert_cloud_danger_cooldown_seconds
risk_alert_state_ttl_seconds

운영 환경의 tfvars 또는 승인된 TF_VAR_... 입력으로 변경한 뒤 build-data-pipe.sh를 다시 실행한다. Cooldown을 너무 짧게 하면 같은 지속 장애가 반복 전송되고, 너무 길게 하면 복구 후 재발 감지가 늦어진다.

권장 판단 순서:

  1. specific/generic 중복이 아닌지 확인
  2. warning confirmation 대상인지 확인
  3. 실제 장애 지속 시간과 교대 대응 시간을 확인
  4. scope와 severity별 cooldown만 조정

안전한 E2E 테스트

운영 데이터와 구분되는 test object를 별도 timestamp/key로 업로드하고, 대상 채널에 테스트임을 사전 공지한다. Factory B/C dummy profile은 synthetic test이므로 실제 사고로 기록하지 않는다.

검증 순서:

  1. test snapshot이 대상 processed/.../state_snapshot/ 또는 processed/cloud_infra/.../ prefix에 생성됐는지 확인
  2. Lambda log에서 rule 결과 확인
  3. warning 확인 대상이면 서로 다른 updated_at의 두 번째 snapshot 생성
  4. Slack 메시지의 scope/reason/source key 확인
  5. DynamoDB last_slack_status=sent와 cooldown 확인
  6. 같은 snapshot 재처리가 skip되는지 확인

실제 webhook URL이나 secret value를 테스트 출력에 포함하지 않는다.


실패 대응

Secret 조회 실패

  1. Lambda 환경 변수에 해당 scope secret ARN이 있는지 확인한다.
  2. aws secretsmanager describe-secret --secret-id <secret-name>으로 metadata를 확인한다.
  3. build script에 지정한 로컬 파일이 존재했는지 확인한다.
  4. IAM policy가 해당 secret ARN의 GetSecretValue를 허용하는지 확인한다.
  5. 파일 경로를 바로잡고 build script를 재실행한다.

Slack HTTP 실패

  1. Lambda log와 last_slack_error를 확인한다.
  2. webhook 폐기, 채널 변경, timeout 여부를 확인한다.
  3. 새 webhook value를 로컬 파일에 넣고 build script로 재주입한다.
  4. 실패 전 예약된 cooldown이 남아 있음을 고려한다. 즉시 반복 업로드부터 하지 말고 cooldown_until을 확인한다.

알림이 오지 않음

  1. S3 notification prefix와 .json suffix가 맞는지 확인한다.
  2. snapshot parser가 지원하는 key인지 확인한다.
  3. rule 결과가 normal인지 확인한다.
  4. warning confirmation 대기 또는 cooldown 상태인지 확인한다.
  5. 해당 scope의 secret routing과 Lambda log를 확인한다.

알림이 너무 많음

  1. 동일 section의 specific/generic이 함께 생성되는지 테스트로 확인한다.
  2. 서로 다른 reason이면 별도 fingerprint이므로 각각 전송될 수 있음을 확인한다.
  3. Factory freshness는 Cloud Slack에서 제외되고 Factory pipeline alert로만 오는지 확인한다.
  4. 임계값보다 먼저 cooldown을 조정하되, 실제 danger를 숨기지 않도록 severity별로 분리한다.

관련 문서

Aegis-Pi Wiki

· 대표 문서 목록은 홈의 문서 탐색 표 참조

시작하기

요구사항

핵심 개념

아키텍처

컴포넌트 (Edge → Cloud → Dashboard)

Dashboard & 운영

시나리오 · 사례 · 참조

Clone this wiki locally