一个EBS卷在它挂载的实例被删掉之后还能活着。一个弹性IP在迁移完成之后还能继续存在。一个NAT网关在它服务的VPC去年就被拆掉之后,还在按小时计费。它们每一个都在默默产生账单,却什么都不报告。 Cost Explorer只给你看总数,Trusted Advisor只给你列候选。真正能推动你做决定的那个数字,是点名某一个资源、并给出它每月花多少钱。zombiescan这个工具,就是为22类资源产出这个数字的。 它到底检查什么 这22项检查覆盖了存储、计算、网络、数据服务,以及那些不属于任何区域的账户级服务。其中17项会产生月度费用,另外5项本身不花钱,但会被报告出来——因为它们会无限累积,并且挡住删除操作。 available-eni:未挂载的网络接口 detached-internet-gateway:没有挂到任何VPC的互联网网关 disabled-kms-key:已禁用但仍在计费的KMS密钥 empty-classic-lb:没有实例的经典负载均衡器 empty-vpc:里面什么都没有的VPC idle-load-balancer:没有注册目标的负载均衡器 idle-nat-gateway:闲置的NAT网关 idle-provisioned-dynamodb:按预置计费的空DynamoDB表 incomplete-multipart-upload:存有未完成分片上传的S3桶 log-group-no-retention:没有保留策略的日志组 orphaned-rds-snapshot:已删除数据库的手动RDS快照 orphaned-snapshot:孤立的EBS快照 stale-secret:90天内没有任何读取的密钥 stopped-instance:已停止但仍在为存储计费的实例 stopped-rds-instance:已停止但仍在为存储计费的RDS实例 unassociated-eip:未关联的弹性IP unattached-ebs:未挂载的EBS卷 unmounted-efs:没有挂载目标的EFS文件系统 unused-ami:没有任何实例使用的AMI unused-route53-health-check:没有记录使用的Route 53健康检查 unused-security-group:没有挂到任何东西的安全组 unused-vpc-endpoint:没有工作负载的接口型VPC终端节点 那5项零成本检查分别是:未挂载的网络接口、未使用的安全组、空VPC、未挂载的互联网网关,以及没有保留策略的日志组。 只读,不删任何东西 扫描过程中发出的每一次调用都是Describe、List或Get。整个扫描没有任何一条代码路径会去删除、终止、修改或释放任何资源。这一点在权限设计上是有意为之的。 安装方式是通过uv工具直接从Git仓库拉取。需要注意的是,botocore的CRT扩展是硬依赖——boto3通过它的登录凭证提供程序读取aws login会话,如果没有装这个扩展,凭证加载阶段就会抛出MissingDependencyException。 加上--all-regions参数时,工具会先问EC2这个账户启用了哪些区域,所以被主动关闭的区域不会产生任何调用。对一个规模不大的账户来说,22项检查扫17个区域,大约20秒跑完。 全局服务每次扫描只跑一遍。Route 53没有区域概念,如果一项检查在17个区域里各跑一次,同一个健康检查会被报告17次,总数也会跟着翻17倍。 价格表是打包进去的 随包附带的价格表由AWS Price List API生成,可以用一条命令刷新。把价格表打包进工具里有两个好处:扫描可以完全离线进行,同时权限清单里可以去掉pricing:GetProducts这一项。每份报告都会记录价格表的生成日期,读报告的人能知道这些数字是按哪一版费率算出来的。 区域对结果的影响大到足以改变决策。一个统一的固定费率会把圣保罗的NAT网关价格算低一半,同时把那里的gp3价格低估90%。 一条Price List记录里可能包含多个价格维度。S3存储会在同一条记录里列出所有容量层级,DynamoDB预置容量则会在计费费率旁边列出一个0.00美元的免费额度维度。选取所请求单位对应的最高正费率,得到的就是账户在层级和免费额度生效之前实际支付的费率。 报告里的详情表会把最贵的发现排在前面,同时保证每一项触发的检查都至少有一行记录。数字前面的波浪号表示这是一个估算值或上限值,出现这种情况有三种原因:该区域没有价格记录、数字回退到了us-east-1;资源类型无法识别;或者该资源按实际存储量而非预置量计费。每一条发现在JSON输出里都带有说明,指明具体是哪种情况。 如果只想看大额项,--min-cost 5可以隐藏每月低于5美元的发
2026-09-23