개요
AWS 인프라를 운영하다 보면 리소스가 의도치 않게 변경되거나, 보안 정책을 위반하는 구성이 발생할 수 있다. 이를 체계적으로 추적하고 감사하기 위해 AWS Config를 도입했다.
현재 서울(ap-northeast-2)과 us-east-1(CloudFront 전용) 두 리전에 걸쳐 총 44개 규칙(관리형 40개 + Custom Lambda 4개)을 운영하며, Terraform으로 전체 구성을 관리한다.
Config Recorder (리소스 기록)
서울 리전
실시간(CONTINUOUS) 기록 방식으로, 선택적 리소스 타입만 모니터링한다.
| 리소스 타입 | 주요 대상 |
|---|---|
| EC2 (Instance, SecurityGroup, Volume, VPN, EIP, ENI) | 서버, 보안 그룹, 스토리지 |
| IAM User | 사용자 계정 |
| ECS (Cluster, Service, TaskDefinition) | 컨테이너 서비스 |
| CloudWatch Alarm | 모니터링 경보 |
| S3 Bucket | 스토리지 |
| EFS FileSystem | 파일 스토리지 |
| ALB/NLB | 로드밸런서 |
| CloudFront Distribution | CDN |
| Lambda Function | 서버리스 |
| ElastiCache | 캐시 |
기록된 구성 변경 이력은 S3 버킷에 저장된다.
us-east-1 리전 (CloudFront 전용)
CloudFront Config Rules는 us-east-1에서만 사용 가능하여 별도 리전에 구성했다. AWS::CloudFront::Distribution만 기록한다.
Config Rules (총 44개)

평가 주기
| 주기 유형 | 설명 |
|---|---|
| 변경 시 | 해당 리소스가 생성/수정/삭제될 때 즉시 평가 |
| 3시간 | Custom Lambda 기반 주기적 평가 |
| 24시간 | AWS 관리형 규칙 주기적 평가 |
목적 태그
| 태그 | 의미 |
|---|---|
| 보안 | 데이터 보호, 접근 제어, 암호화, 공격 방어 |
| 성능 | 가용성, 모니터링, 장애 감지 |
| 비용 | 불필요한 리소스/지출 방지 |
S3 보안 (3개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
s3-bucket-public-read-prohibited | 변경 시 | 보안 | 퍼블릭 읽기 허용 시 민감 데이터 유출 위험 |
s3-bucket-public-write-prohibited | 변경 시 | 보안 | 퍼블릭 쓰기 허용 시 악성 파일 업로드 및 데이터 변조 위험 |
s3-bucket-server-side-encryption-enabled | 변경 시 | 보안 | 저장 데이터 암호화 미적용 시 유출 위험 |
s3-bucket-ssl-requests-only는 S3 퍼블릭 차단 + CloudFront HTTPS로 충분하여 제거.s3-bucket-versioning-enabled는 버킷 용도에 따라 필요성이 다르므로 개별 적용.
EC2 / EBS (11개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
cloudwatch-alarm-resource-check | 3시간 | 성능 | 경보가 데이터 부족·비활성 상태면 모니터링 사각지대 |
cloudwatch-alarm-resource-check_CPUUtilization | 24시간 | 성능 | CPU 이상 감지 알람 없으면 장애 인지 지연 |
cloudwatch-alarm-resource-check-mem_used_percent | 3시간 | 성능 | 메모리 부족 감지 알람 없으면 OOM 장애 위험 |
cloudwatch-alarm-resource-check-disk_used_percent | 3시간 | 성능 | 디스크 풀 감지 알람 없으면 서비스 중단 위험 |
ec2-stopped-instance | 24시간 | 비용 | 30일 이상 정지된 인스턴스는 EBS 비용만 발생 |
ec2-volume-inuse-check | 변경 시 | 비용 | 미연결 EBS 볼륨은 불필요한 스토리지 비용 발생 |
ebs-snapshot-public-restorable-check | 24시간 | 보안 | 퍼블릭 스냅샷은 누구나 복원 가능하여 데이터 유출 위험 |
ec2-imdsv2-check | 변경 시 | 보안 | IMDSv1은 SSRF 공격으로 자격증명 탈취 가능 |
ec2-ebs-encryption-by-default | 24시간 | 보안 | EBS 기본 암호화 미적용 시 신규 볼륨 평문 저장 |
ec2-termination-protection-enabled | 24시간 | 보안 | 종료 방지 미설정 시 실수로 인스턴스 삭제 가능 |
eip-attached | 변경 시 | 비용 | 미연결 EIP는 시간당 과금 발생 |
IAM 보안 (5개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
iam-user-mfa-enabled | 24시간 | 보안 | MFA 미설정 시 비밀번호 유출만으로 계정 탈취 가능 |
iam-password-policy | 24시간 | 보안 | 약한 비밀번호 정책은 무차별 대입 공격에 취약 |
iam-root-access-key-check | 24시간 | 보안 | 루트 액세스 키 존재 시 전체 계정 탈취 위험 |
iam-user-unused-credentials-check | 24시간 | 보안 | 90일 이상 미사용 자격증명은 유출되어도 인지 불가 |
access-keys-rotated | 24시간 | 보안 | 장기간 미교체 키는 유출 시 피해 기간 증가 |
ECS 컨테이너 (5개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
ecs-task-definition-log-configuration | 변경 시 | 성능, 보안 | 로그 미수집 시 장애 원인 분석 및 보안 감사 불가 |
ecs-containers-nonprivileged | 변경 시 | 보안 | privileged 모드는 호스트 전체 접근 권한 부여 |
ecs-containers-readonly-access | 변경 시 | 보안 | 쓰기 가능 루트 파일시스템은 악성코드 설치 위험 |
ecs-fargate-latest-platform-version | 변경 시 | 보안, 성능 | 구버전 플랫폼은 보안 패치 미적용 및 성능 개선 누락 |
ecs-no-environment-secrets | 변경 시 | 보안 | 환경변수에 시크릿 노출 시 로그·콘솔에서 평문 확인 가능 |
Lambda (2개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
lambda-function-settings-check | 변경 시 | 보안, 성능 | 지원 종료 런타임은 보안 패치 중단 |
lambda-function-public-access-prohibited | 변경 시 | 보안 | 퍼블릭 접근 허용 시 무단 실행 및 비용 폭증 위험 |
네트워크 / 로드밸런서 (7개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
restricted-ssh | 24시간 | 보안 | SSH 포트 퍼블릭 오픈은 무차별 대입 공격 대상 |
vpc-vpn-2-tunnels-up | 변경 시 | 성능 | VPN 터널 1개만 UP이면 장애 시 연결 단절 |
vpc-sg-open-only-to-authorized-ports | 변경 시 | 보안 | 불필요한 포트 오픈은 공격 표면 확대 |
elb-deletion-protection-enabled | 변경 시 | 보안 | 삭제 보호 미설정 시 실수로 LB 삭제 가능 |
alb-waf-enabled | 변경 시 | 보안 | WAF 미연결 ALB는 웹 공격에 노출 |
vpc-default-security-group-closed | 변경 시 | 보안 | 기본 SG에 규칙이 있으면 의도치 않은 트래픽 허용 |
vpc-flow-logs-enabled | 24시간 | 보안 | Flow Logs 미활성 시 네트워크 이상 트래픽 감사 불가 |
ElastiCache (3개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
elasticache-repl-grp-encrypted-in-transit | 변경 시 | 보안 | 전송 중 미암호화 시 캐시 데이터 도청 가능 |
elasticache-repl-grp-encrypted-at-rest | 변경 시 | 보안 | 저장 시 미암호화 시 스냅샷에서 데이터 유출 위험 |
elasticache-repl-grp-auto-failover-enabled | 변경 시 | 성능 | 자동 페일오버 미설정 시 노드 장애 시 수동 복구 필요 |
스토리지 (1개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
efs-encrypted-check | 24시간 | 보안 | EFS 미암호화 시 저장 데이터 유출 위험 |
감사 (2개)
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
cloudtrail-enabled | 24시간 | 보안 | CloudTrail 미활성 시 API 호출 이력 추적 불가 |
wafv2-logging-enabled | 24시간 | 보안 | WAF 로깅 미활성 시 차단된 공격 분석 불가 |
CloudFront (6개): us-east-1
| 규칙명 | 평가 주기 | 목적 | 왜 지켜야 하는가 |
|---|---|---|---|
cloudfront-viewer-policy-https | 변경 시 | 보안 | HTTP 허용 시 평문 트래픽 도청 가능 |
cloudfront-origin-failover-enabled | 변경 시 | 성능 | 오리진 장애 시 페일오버 없으면 서비스 중단 |
cloudfront-s3-origin-access-control-enabled | 변경 시 | 보안 | OAC 미설정 시 S3 버킷 직접 접근 가능 |
cloudfront-associated-with-waf | 변경 시 | 보안 | WAF 미연결 시 웹 공격에 노출 |
cloudfront-accesslogs-enabled | 변경 시 | 보안 | 액세스 로그 미활성 시 트래픽 감사 불가 |
cloudfront-no-deprecated-ssl-protocols | 변경 시 | 보안 | 구버전 SSL은 알려진 취약점 존재 |
WAF 현황
| 항목 | 상태 |
|---|---|
| Regional WAF (ALB용) | 미설정 (CloudFront WAF로 대체) |
| CloudFront WAF (us-east-1) | 3개 배포 모두 연결 |
ALB는 CloudFront 뒤에 위치하여 WAF 이중 적용이 불필요하므로, Config 규칙에서 예외 처리했다.
일일 규정 준수 리포트 자동화
Lambda: AWSConfigRulesMailProvider
| 항목 | 설정값 |
|---|---|
| 런타임 | Python 3.13 (arm64) |
| 트리거 | EventBridge Scheduler: 평일 매일 09:00 KST |
| 발송 방식 | SES HTML 메일 |
보고서 기능
- 서울 + us-east-1 양쪽 리전 규칙 수집
- 카테고리별 규칙 그룹핑 (S3, EC2, IAM, ECS, Lambda, 네트워크, ElastiCache, CloudFront, 감사)
- 규칙별 목적 태그 표시 (보안 / 성능 / 비용)
- 규칙별 "왜 지켜야 하는가" 한 줄 설명
- 미준수 리소스 상세 목록 (EC2 Name 태그, IAM UserName 매핑)
- 예외 리소스 건수만 표시 (상세 목록 숨김)
- 요약 카드: 전체/준수/미준수/데이터 부족 수치
보고서 자동화 코드
import boto3
config = boto3.client('config')
ses = boto3.client('ses')
def lambda_handler(event, context):
# 서울 + us-east-1 양쪽 리전 규칙 수집
rules = config.describe_config_rules()['ConfigRules']
for rule in rules:
rule_name = rule['ConfigRuleName']
result = config.get_compliance_details_by_config_rule(
ConfigRuleName=rule_name,
ComplianceTypes=['COMPLIANT', 'NON_COMPLIANT']
)
# 카테고리별 그룹핑 + 목적 태그 + 준수/미준수 상태 집계
# 미준수 리소스 상세 목록 (EC2 Name 태그, IAM UserName 매핑)
# 예외 리소스 필터링
# HTML 보고서 생성 후 SES 발송
ses.send_email(
Source='[noreply-email]',
Destination={'ToAddresses': ['[ops-team-email]']},
Message={
'Subject': {'Data': '[사내 인프라] AWS Config 규칙 평가 결과 보고서 (YYYY-MM-DD)'},
'Body': {'Html': {'Data': html_body}}
}
)예외 리소스 관리
Lambda 코드 내 EXCEPTION_RESOURCES 딕셔너리에 규칙별 예외 리소스 ID를 관리한다.
| 규칙명 | 예외 사유 |
|---|---|
ec2-stopped-instance | Standby 인스턴스, 의도적 정지 |
iam-user-mfa-enabled | 서비스 계정 등 MFA 미적용 허용 |
| CloudWatch 알람 검증 규칙 (CPU/메모리/디스크) | 모니터링 대상 외 인스턴스 |
efs-encrypted-check | 기존 EFS는 생성 후 암호화 변경 불가 |
alb-waf-enabled | CloudFront WAF로 보호 중 (ALB 이중 WAF 불필요) |
s3-bucket-public-read-prohibited | 외부 파일 공유 용도 버킷 |
Custom Config Rule (Lambda 연동)
AWS 관리형 규칙으로 커버되지 않는 항목은 Lambda를 직접 작성하여 Config Rule로 연동했다. 현재 Custom Lambda 규칙은 총 4개다.
[Config Rule (Custom, 주기적 트리거)]
↓ 평가 시 Lambda 호출
[Lambda 함수 - 평가 로직 실행]
↓ 평가 결과 반환 (COMPLIANT / NON_COMPLIANT)
[AWS Config 콘솔 반영 + 보고서 포함]
Custom Rule 1: CloudWatch 경보 상태 점검
| 항목 | 설정값 |
|---|---|
| Config Rule | cloudwatch-alarm-resource-check |
| Lambda | CheckCloudWatchAlarmState |
| 평가 주기 | 3시간 |
| 목적 | 성능 |
CloudWatch 경보가 'OK'나 'ALARM'이 아닌 '데이터 부족(INSUFFICIENT_DATA)' 상태로 지속되거나, '비활성화(Disabled)' 상태인지 감지한다. 경보가 데이터 부족이나 비활성 상태면 실제 장애가 발생해도 알림이 오지 않아 모니터링 사각지대가 된다.
Custom Rule 2: 디스크 사용률 알람 검증
| 항목 | 설정값 |
|---|---|
| Config Rule | cloudwatch-alarm-resource-check-disk_used_percent |
| Lambda | CloudWatchMetric-disk_used_perrcent-Verification |
| 평가 주기 | 3시간 |
| 목적 | 성능 |
EC2 인스턴스에 disk_used_percent 메트릭 기반 CloudWatch 알람이 설정되어 있는지 확인한다. 디스크 사용률 알람이 없으면 디스크 풀(100%) 상황을 감지하지 못해 서비스 중단 위험이 있다.
Custom Rule 3: 메모리 사용률 알람 검증
| 항목 | 설정값 |
|---|---|
| Config Rule | cloudwatch-alarm-resource-check-mem_used_percent |
| Lambda | CloudWatchMetric-mem_used_perrcent-Verification |
| 평가 주기 | 3시간 |
| 목적 | 성능 |
EC2 인스턴스에 mem_used_percent 메트릭 기반 CloudWatch 알람이 설정되어 있는지 확인한다. 메모리 사용률 알람이 없으면 OOM(Out of Memory) 장애를 사전에 감지하지 못한다.
Custom Rule 2, 3 수정 이력
디스크/메모리 사용률 검증 Lambda에 다음 수정을 적용했다:
-
ALLOWED_NAMESPACES 추가: 기존에는
CWAgent등 일부 네임스페이스만 허용하여, 커스텀 네임스페이스로 경보가 설정된 인스턴스가 미준수로 잘못 판정되던 문제를 해결했다. -
StateValue="OK" 필터 제거: 기존에는 경보 상태가 "OK"인 것만 조회하여, "ALARM" 또는 "INSUFFICIENT_DATA" 상태의 경보가 매칭 안 되던 문제를 해결했다.
cloudwatch-alarm-resource-check_CPUUtilization은 AWS 관리형 규칙으로AWS/EC2네임스페이스만 사용하여 해당 문제가 없다.
Custom Rule 4: EC2 종료 방지 설정 검증 (신규)
| 항목 | 설정값 |
|---|---|
| Config Rule | ec2-termination-protection-enabled |
| Lambda | ConfigRule-EC2TerminationProtectionCheck |
| 평가 주기 | 24시간 |
| 목적 | 보안 |
EC2 인스턴스에 종료 방지(Termination Protection)가 설정되어 있는지 확인한다. AWS 관리형 규칙에 EC2 종료 방지를 체크하는 규칙이 없어서 Custom Lambda로 직접 구현했다.
종료 방지가 미설정된 인스턴스는 콘솔이나 CLI에서 실수로 삭제(Terminate)할 수 있으며, 운영 중인 인스턴스가 삭제되면 데이터 손실 및 서비스 중단이 발생한다.
Lambda 동작 흐름:
Config (24시간 스케줄 트리거)
→ Lambda 실행
→ EC2 DescribeInstances (running/stopped 인스턴스 목록)
→ 각 인스턴스별 DescribeInstanceAttribute (disableApiTermination)
→ 종료 방지 ON → COMPLIANT
→ 종료 방지 OFF → NON_COMPLIANT
→ Config PutEvaluations (결과 전송)
EC2 종료 방지 설정 방법:
# CLI로 즉시 적용 (재부팅 불필요)
aws ec2 modify-instance-attribute \
--instance-id i-[instance-id] \
--disable-api-termination비용
| 항목 | 월 예상 비용 |
|---|---|
| Config Rules 평가 (44개 규칙) | |
| S3 로그 저장 (Config 이력) | |
| Lambda 보고서 발송 | 무료 (프리티어) |
| SES 메일 발송 | 무료 (프리티어) |
| 총 합계 |
정리
- 서울 + us-east-1 멀티 리전에 걸쳐 44개 Config 규칙 운영 (관리형 40개 + Custom Lambda 4개)
- 보안/성능/비용 3가지 관점으로 규칙을 분류하여 우선순위 기반 대응
- AWS 관리형 규칙에 없는 항목(경보 상태 점검, 메트릭 알람 검증, 종료 방지 체크)은 Custom Lambda로 직접 구현
- 평일 매일 09:00 HTML 보고서 자동 발송으로 운영 부담 감소
- 예외 리소스 관리로 오탐 최소화
- Terraform으로 전체 Config 구성 코드화 (IaC)
- 월
$1012 수준의 저비용 운영
배운 점
규칙을 44개까지 늘리면서 배운 건, 감사 체계의 난이도는 규칙 수가 아니라 예외 관리에 있다는 점이다. 위반으로 잡히지만 의도된 구성이 항상 있다. 그걸 정리하지 않으면 보고서는 매일 같은 항목을 반복하고, 사람은 곧 보고서를 열지 않는다.
관리형 규칙에 없는 항목을 Custom Lambda로 직접 만든 것도 기준 때문이었다. AWS가 제공하는 범위가 우리의 기준일 필요는 없다. 경보가 실제로 살아 있는지 점검하는 규칙은 우리 운영에서 나온 요구였다.
Terraform으로 전부 코드화한 덕분에 규칙이 왜 생겼는지 추적할 수 있게 됐다. 사람의 행위를 추적하는 쪽은 AWS CloudTrail + Athena 감사 로그 분석 환경 구축에 따로 정리했다.
이어 읽기
- AWS CloudTrail + Athena 감사 로그 분석 환경 구축: 설정이 아니라 행위를 추적하는 축
- Amazon SES 기반 이메일 알림 인프라 구축: 일일 보고서가 나가는 경로