S3オブジェクトを削除してもストレージコストが下がらない理由と対策をまとめてみた
質問
S3のオブジェクトを削除しているのに、ストレージコストが下がりません。原因を教えてください。
3行まとめ
- S3バケットのバージョニングが有効になっていないか確認しよう
- バージョニングが有効な場合、「論理的な削除」だと、オブジェクト容量は減らないので注意しよう
- S3ライフサイクルルールを使用し、古いバージョンのオブジェクトを簡単に削除しよう
前提知識の解説
バージョニングの基本的な仕組み
S3のバージョニング機能は、同一のバケット内で1つのオブジェクトに対して複数のバージョンを保持する機能です。
以下のような特徴があります。
- バケットごとに設定が可能
- 一度有効化すると、無効化はできない(一時停止は可能)
- 各バージョンは完全なオブジェクトとして保存され、それぞれのストレージコストが発生
削除時の動作
バージョニングが有効なバケットでは、オブジェクトの削除時に以下のような動作をします。
-
通常の削除(バージョンIDを指定しない)の場合
- オブジェクトは実際には削除されない
- 代わりに「削除マーカー」が作成され、それが最新バージョンとなる
- GETリクエストに対して404エラーを返すため、削除されたように見える
# 論理的な削除コマンド(削除マーカーを作成) aws s3api delete-object \ --bucket my-bucket \ --key path/to/my-file.txt
-
バージョンを指定した削除の場合
- 指定されたバージョンのオブジェクトが完全に削除される
- この操作は元に戻すことができない
# 完全な削除コマンド(特定バージョンを削除) aws s3api delete-object \ --bucket my-bucket \ --key path/to/my-file.txt \ --version-id "versionId123456789"
今回の事象
アカウント調査
以下の流れで、アカウントを調査しました。
-
問題の発見
- S3ストレージコストが期待通りに減少していない
- オブジェクトを削除したはずなのに、請求額に大きな変化がない
-
現状確認
- Cost Explorerで使用タイプを「APN1-TimedStorage-ByteHrs(GB-Month)」「APN2-TimedStorage-ByteHrs(GB-Month)」に絞ってオブジェクト容量を確認
- 2025/1/10頃に5TB程度削除作業を実施したようだが、オブジェクト容量が減っていないことを確認
- CloudWatchで全S3バケットの「BucketSizeBytes」を確認するも全て右肩上がりで、オブジェクト容量が減っていないことを確認
-
バケットの確認
- 1番容量が多いバケットの設定を確認したところ、バージョニングが有効になっていることを確認
- S3コンソールでバージョンの表示を有効にしたところ、以前のバージョンのオブジェクトが大量に残っていることを確認
- 1番容量が多いバケットの設定を確認したところ、バージョニングが有効になっていることを確認
-
原因の判明
- バージョニングされたオブジェクトが多数残っていた
- 2025/1/10頃に実施した削除は「論理的な削除」であり、ストレージコストが継続して発生していた
対応
古いバージョンのオブジェクトは全て削除して問題ないとのことで、S3ライフサイクルルールを利用した古いバージョンの削除方法を実施していただきました。
ライフサイクルルールの設定手順
- AWSマネジメントコンソールにログインし、S3サービスにアクセスします。
- 対象のバケットを選択し、上部タブから「管理」を選択します。
- 「ライフサイクルルール」セクションで「ルールの作成」ボタンをクリックします。
- ライフサイクルルール名を入力します(例:「CleanupOldVersions」)。
- ルールのスコープを選択します
- バケット内のすべてのオブジェクトに適用する場合は「バケット内のすべてのオブジェクトに適用」を選択
- 特定のフォルダやプレフィックスのみに適用する場合は「特定のフィルターを使用してオブジェクトを制限」を選択し、プレフィックスやタグを指定
- 「ライフサイクルルールのアクション」セクションで以下の2つにチェックを入れます
- 「オブジェクトの非現行バージョンを完全に削除」 にチェック
- 「期限切れのオブジェクト削除マーカーを削除する」 にチェック
- 「オブジェクトの非現行バージョンを完全に削除」の日数を設定します
- 非現行バージョンを何日後に削除するかを指定します(例:1日)
- これにより、新しいバージョンがアップロードされてから指定日数が経過した古いバージョンが自動的に削除されます
- 「作成」ボタンをクリックしてルールを保存します。
設定時の注意点
- 削除は永久的です
- ライフサイクルルールによって削除されたオブジェクトは復元できません。 設定前にバージョニングが必要なオブジェクトがないかどうか再度ご検討ください。
- バージョニングは誤削除からの保護や変更履歴の保持のために有用ですので、ライフサイクルルールを設定する際は、バージョニングを有効にしている目的に照らし合わせて適切な保持期間を設定してください。
- 即時反映ではありません
- ライフサイクルルールの設定後、AWSがルールを適用するまで最大24時間かかる場合があります。
- 既存の古いバージョンにも適用されます
- 設定したルールは、既存の古いバージョンにも適用されます。例えば、1日の設定をした場合、すでに1日以上経過している非現行バージョンは次回のライフサイクルアクションの実行時に削除対象となります。
設定後の確認方法
ライフサイクルルールが正しく機能しているかを確認する方法は以下の通りです。
- S3コンソールで「バージョンの表示」を有効にし、オブジェクトの古いバージョンが指定した期間後に削除されているか確認する
- CloudWatchメトリクスで「BucketSizeBytes」を監視し、ストレージ使用量の減少を確認する、もしくはCost Explorerで「TimedStorage-ByteHrs」の推移を確認する(S3 Storage Lensの利用ももちろん可能)
対応後
2025/3/25にライフサイクルルールの設定及び不要なオブジェクトの削除を実施いただき、全体のオブジェクト容量を1/3程度にすることができました。
これにより、これまで毎日約18ドルかかっていたS3コストを1/3の約6ドルまで削減することができ、 月360ドル 程度削減することができました。
また、S3 Storage Lensも再有効化していただき、「コスト最適化」の観点を定期的に確認するようにしていただきました。
無駄なオブジェクトがほとんどないので、バッチリですね!
さいごに
今回は、S3のバージョニング機能が有効な場合のオブジェクト削除の挙動と、それに関連するストレージコストの問題について解説しました。
単純な削除操作では見た目上は削除されたように見えても、実際にはストレージコストが発生し続ける可能性があるため、適切なライフサイクルルールの設定が重要です。
最後までお読みいただきありがとうございました!
以上、おつまみ(@AWS11077)でした!