結論:請求書の80%は「動いていない待機リソース」だった
私の個人開発AWSアカウントは月の請求が約8万円。内訳を Cost Explorer で分解したら、アプリ本体(EC2/RDS)以外の待機系リソースが3万円超を占めていました。NAT Gateway 2本、デタッチ済みEBS、未関連EIP——どれも「使っていないのに課金され続ける」典型です。掃除した結果、翌月の請求は約5万円に。手順を全部公開します。
なぜ気づきにくいのか(根拠)
これらは「起動中インスタンス」の一覧に出てこないため、コンソールのEC2ダッシュボードを眺めても発見できません。課金体系を押さえると理由が明確です。
| リソース | 課金条件 | 東京リージョン概算 |
|---|---|---|
| NAT Gateway | 存在するだけで時間課金+転送量 | $0.062/h ≈ 月¥7,000/本 |
| EBS (gp3) | アタッチ有無に関係なく容量課金 | $0.096/GB·月 |
| EIP | インスタンス未関連だと課金 | $0.005/h ≈ 月¥550/個 |
NAT Gateway は冗長化でAZごとに作ると本数が増え、検証用VPCに作ったまま放置しがちです。
手順1:未使用EIPを掃除する
関連付けされていない(AssociationId が無い)EIPを一覧化します。
aws ec2 describe-addresses \
--query "Addresses[?AssociationId==null].[PublicIp,AllocationId]" \
--output table
確認したら解放します。
aws ec2 release-address --allocation-id eipalloc-0123456789abcdef0
手順2:デタッチ済みEBSボリュームを掃除する
ステータスが available(=どこにもアタッチされていない)ボリュームを総容量つきで洗い出します。
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query "Volumes[].[VolumeId,Size,CreateTime]" \
--output table
削除前に必ずスナップショットを取ってから消すのが安全です。
# 念のため退避
aws ec2 create-snapshot --volume-id vol-0abc --description "pre-delete backup"
# 確認後に削除
aws ec2 delete-volume --volume-id vol-0abc
旧世代の gp2 が残っていたら、削除せず使う場合でも gp3 への変更で約20%安くなります。
aws ec2 modify-volume --volume-id vol-0abc --volume-type gp3
手順3:不要なNAT Gatewayを掃除する
最大の出費源。まず全リージョンで棚卸しします。
aws ec2 describe-nat-gateways \
--filter Name=state,Values=available \
--query "NatGateways[].[NatGatewayId,VpcId,SubnetId]" \
--output table
検証用VPCや、もうプライベートサブネットから外向き通信が不要になったものを削除します。
aws ec2 delete-nat-gateway --nat-gateway-id nat-0123456789abcdef0
注意:NAT Gateway削除後、解放されるEIPが残るので手順1で再チェック。プライベートサブネットからS3/ECRへ通信しているだけなら、NATをVPCエンドポイント(Gateway型なら無料)へ置き換えるとさらに削減できます。
aws ec2 create-vpc-endpoint \
--vpc-id vpc-0abc \
--service-name com.amazonaws.ap-northeast-1.s3 \
--route-table-ids rtb-0abc
再発防止:毎月自動で棚卸しする
掃除は一度やっても放置すればまた溜まります。AWS Budgets でしきい値超過時にメール通知を仕込み、上記3コマンドを月初に走らせるシェルをcronやLambdaに置いておくのが効果的です。
# 待機リソースを一括チェックするワンライナーの例
for r in ap-northeast-1 us-east-1; do
echo "== $r =="
aws ec2 describe-addresses --region $r \
--query "Addresses[?AssociationId==null].PublicIp" --output text
aws ec2 describe-volumes --region $r \
--filters Name=status,Values=available --query "Volumes[].VolumeId" --output text
done
まとめ
- 請求の主犯は起動一覧に出ない待機リソース:NAT Gateway・available なEBS・未関連EIP。
- 棚卸しは
describe-addresses/describe-volumes/describe-nat-gatewaysの3コマンドで足りる。 - 削除前にスナップショット、S3/ECR向けはVPCエンドポイントへ置換。
- 最後に
AWS Budgets+月次自動チェックで再発を止める。
リージョンを跨いだ確認を忘れると「us-east-1に作った検証用NATが生き残る」事故が起きます。全リージョン棚卸しだけは必ず習慣化してください。
関連リンク
※自社商品(プロモーションを含みます)。
Top comments (0)