원문 캡처 · github.com
원문 캡처 · github.com

zombiecost는 AWS 계정에서 사용하지 않거나 잊힌 자원을 찾아 예상 월 비용을 보여주는 읽기 전용 도구다. AWS 자원 정리 대상을 확인하려는 운영자는 결과를 보고 실제 청구액이 아닌 대략적인 비용 규모를 파악할 수 있다.

검사 항목찾는 자원비용 추정 기준
ebs-unattached연결되지 않은 EBS 볼륨볼륨 유형별 GB-월 가격
eip-unused연결되지 않은 탄력적 IP미사용 시간당 요금
snapshots-old소유한 AMI에서 사용하지 않으며 90일이 지난 스냅샷GB-월 스냅샷 가격
ec2-idle조회 기간 평균 CPU 사용률이 3% 미만인 실행 중 인스턴스온디맨드 시간당 가격
nat-idle조회 기간 전송량이 1GiB 미만인 NAT 게이트웨이시간당 NAT 요금
rds-idle조회 기간 연결이 0회인 RDS 인스턴스인스턴스 클래스와 스토리지
lb-unused등록된 대상이 없거나 요청을 0건 처리한 ALB시간당 로드 밸런서 요금
s3-stale180일 동안 쓰기 작업이 없었던 버킷스토리지 클래스별 GB-월 가격

비용은 us-east-1의 온디맨드 가격을 기준으로 한 대략적인 추정치이며, 실제 청구서와 일치하는 값이 아니라 비용 규모를 가늠하기 위한 것이다. 사용 이력에 의존하는 ec2-idle, rds-idle, nat-idle, lb-unused 검사는 생성된 지 3일이 지나지 않은 자원을 유휴 상태로 보고하지 않는다. s3-stale은 쓰기 작업은 확인하지만 읽기 작업은 확인할 수 없다. 유료 요청 지표 없이는 읽기를 볼 수 없다는 점을 각 결과에 표시한다.

설치와 실행

PyPI에서 설치하거나 저장소를 복제해 개발용으로 설치할 수 있다.

bash
pip install zombiecost
bash
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

기본 프로필로 활성화된 모든 리전을 검사한다. 프로필과 리전을 지정하거나 조회 기간을 30일로 늘려 JSON 보고서를 만들 수도 있다.

bash
zombiecost # every enabled region, default profile
zombiecost --profile prod --regions eu-west-1,us-east-1
zombiecost --days 30 --json report.json # longer lookback, machine-readable output
zombiecost --redact # placeholders instead of IDs, names and IPs: safe to paste publicly
zombiecost --skip s3-stale # never list object keys
zombiecost --only ebs-unattached,eip-unused # just the fast, metadata-only checks
zombiecost --list-checks

권한과 데이터 처리

도구는 자체 서버나 다른 서비스로 데이터를 보내지 않으며, 사용자 자격 증명으로 AWS API를 호출한다. 제작자에 따르면 원격 통신이 가능한 런타임 의존성은 boto3 하나이고, 이 도구가 호출하는 API는 Describe, List, Get뿐이다. 자원을 생성·변경·삭제하는 코드 경로는 없다.

s3-stale 검사는 객체 수준 정보에 접근하는 유일한 검사다. 가장 최근 수정 시점을 찾으려고 객체 키를 나열한 뒤 폐기하며, 키를 저장하거나 출력하지 않는다. 키를 나열하지 않으려면 --skip s3-stale를 사용하고 정책에서 s3:ListBucket 권한을 제거할 수 있다.

일반 출력과 --json에는 실제 자원 ID, 이름, 태그, IP 주소가 포함된다. 공유할 보고서에는 --redact를 사용하면 ID·이름·IP 주소·계정 번호가 일관된 대체값으로 바뀌고, 각 결과의 details 블록은 제외된다.

스캔에는 ReadOnlyAccess를 연결하거나 다음 최소 권한 정책을 사용할 수 있다.

json
{
 "Version": "2012-10-17",
 "Statement": [{
 "Effect": "Allow",
 "Action": [
 "sts:GetCallerIdentity",
 "ec2:DescribeRegions",
 "ec2:DescribeVolumes",
 "ec2:DescribeAddresses",
 "ec2:DescribeSnapshots",
 "ec2:DescribeImages",
 "ec2:DescribeInstances",
 "ec2:DescribeNatGateways",
 "rds:DescribeDBInstances",
 "elasticloadbalancing:DescribeLoadBalancers",
 "elasticloadbalancing:DescribeTargetGroups",
 "elasticloadbalancing:DescribeTargetHealth",
 "s3:ListAllMyBuckets",
 "s3:GetBucketLocation",
 "s3:ListBucket",
 "cloudwatch:GetMetricStatistics",
 "cloudwatch:ListMetrics"
 ],
 "Resource": "*"
 }]
}

테스트는 AWS 계정 없이 moto를 대상으로 pytest로 실행한다. 로드맵에는 사용하지 않는 KMS 키·Secrets Manager 시크릿·VPC 엔드포인트, 중지된 인스턴스의 볼륨 비용, 오래된 AMI와 관련 스냅샷 검사, 교차 계정 역할과 주간 검사 및 Slack 알림을 포함한 호스팅 버전이 올라 있다.

취약점 제보 안내는 SECURITY.md에서 확인할 수 있다.