こんにちは!shiroです(^o^)/
「株式会社ネクスウェイ Advent Calendar 2025」3日目の記事です!
今回はSREっぽくインフラ周りでお勉強したことをアウトプットしてみます…!
先輩に大迷惑をおかけしながら、S3バケットの削除を行った手順などのまとめです(遠い目)
🌟 経緯ダイジェスト
S3に保管してたオブジェクトデータを削除したいが、実行に数日間かかりそう…!
クラメソさんに問い合わせるも、まさかの非同期実行できない!?
コマンド実行が終わるまで待ち続けるわけにもいかないし、これは困ったぞ…。
というわけで、本記事ではレプリケーション&バージョニングが有効なS3バケットをどうやって削除したかをまとめてみます!
■ 対象読者
- バージョニングが有効なレプリケーション先のバケットに保管していたオブジェクトを、バケットごと葬り去りたい方 ⚰️
▌経緯詳細
■ 状況
- S3バケットから別のバケットへデータをレプリケートしていたが、不要になった
- 対象のバケットはバージョニングが有効
- レプリケーションも有効
- オブジェクト数は膨大で、削除には丸1日以上かかりそうな見込み
- 削除の実行は運用専門のチームに行ってもらうため、1ポチで対応が完了するジョブを作る必要がある
■ 直面した問題
当初はLambda、もしくはCodebuild上でAWS CLIのコマンド(aws s3 rm)でオブジェクト削除を実行しようとしていましたが、
調べたり問い合わせたりした結果、以下の問題に直面しました。
- 実行時間が長すぎる: CLIで削除を試みる場合、単純計算だと数日かかりそう
- 非同期実行できない: API経由での削除は同期的に行われるため、数日間実行しっぱなしになる
つまり、Lambda/Codebuildのタイムアウト値による途中中断、ないしは長時間稼働による利用料への影響が懸念されました。
AWSサポートに問い合わせたところ、AWS CLIコマンドの非同期での処理はできないためライフサイクルルール設定で削除することを勧められました。
そこで、まずはライフサイクルルールを適用してオブジェクトを論理削除(削除マーカー付与)→物理削除(期限切れオブジェクト&削除マーカーの破棄)し、その後実際にバケットを削除するという2段階構成でそれぞれジョブを作成する作戦に切り替えました!
▌削除作戦の全体像
※ S3の削除を自動化するために、AWS Lambdaとjenkinsを使って削除フローを構築しました
■ 前半フェーズのジョブを実行
❶ レプリケーションの停止:
安全にレプリケーションルールを削除するため、前半の段階で停止させておきます。
❷ 論理削除(ライフサイクルルールの適用):
オブジェクトを1日後に削除(削除マーカーを付与し過去バージョン化)するライフサイクルルールを適用。
■ 2日間の待機
❸ 物理削除(ライフサイクルルール実行)待ち:
対象となるいずれのバケットにおいても、「過去バージョンのオブジェクトと削除マーカー(論理削除済みのオブジェクト)が存在した場合、1日後に完全に削除する」ライフサイクルルールを適用済みのため、それが実行されるのを待ちます。
■ 後半フェーズのジョブを実行
❹ レプリケーションルールの削除:
レプリケーションルールが無効化されていることを確認し、対象のルールを削除します。
⚠️ 注意 ⚠️
レプリケーション先のバケットを先に削除してしまうと、その後レプリケーションルールが削除できなくなる可能性があります!
マネジメントコンソール上でレプリケーションルールの操作が不能になり、AWS CLIを用いて「先にバケットを削除してしまったレプリケーションルール」の除外と更新を行う必要があります。
これで一度手詰まってしまった歴史があると先輩から再三勧告を受けました。
❺ バケット削除:
バケットが空になっていることを確認して、バケット削除の実行。
▌実装の詳細
■ 構成
既存ジョブや権限管理の兼ね合いで、それぞれの処理を実行するAWS Lambdaをフェーズごとに2つのJenkinsジョブに分けてそれぞれラップする構成としました!
◆ 前半フェーズ|レプリケーション停止と論理削除のジョブについて
このフェーズの目的は、オブジェクトを「物理削除待ち」の状態にすることです。
1. Lambda
以下の3つのLambdaを用意し、Jenkinsから順次(または選択して)実行できるようにしました。
| Lambdaの役割 | 詳細 | |
|---|---|---|
| ⅰ | 権限付与 | JenkinsからS3操作を許可するバケットポリシー/IAMロールの設定 |
| ⅱ | レプリケーション無効化 | 対象バケットのレプリケーションルールを取得し、Statusの値をDisableに変更して戻す |
| ⅲ | 論理削除のライフサイクルルール適用 | 対象バケットのライフサイクルルールを取得し、現行オブジェクトを作成から1日後(即時)に失効させるライフサイクルルールを追記して戻す |
※Lambda ⅲ(論理削除のライフサイクルルール適用)について
前提として、対象バケットには既に「非現行バージョンのオブジェクトと削除マーカーを物理削除するライフサイクルルール」が適用されています。
つまり、「ライフサイクルルールを追加する」処理だけを実行すると、物理削除のライフサイクルルールが上書きされ、論理削除ルールのみが付与された状態になってしまいます。
そのため、今回作成したジョブでは、一度すべてのライフサイクルルール設定を取得し、論理削除のライフサイクルルールを追記して戻す形を取っています。
2. Jenkins
上記3つのLambdaをラップするパイプラインです
機能:
- Lambda ⅰ(権限付与)は常時実行
- Lambda ⅱ(レプリケーション停止)、Lambda ⅲ(論理削除)はパラメータで実行有無を選択可能
- 実行結果(成功/失敗)をSlackへ通知
◆ 後半フェーズ|レプリケーションルールの削除とバケット削除
このフェーズでは、オブジェクトが完全に削除されたことを確認後、バケット自体の削除を行います。
1. Lambda
| Lambdaの役割 | 詳細 | |
|---|---|---|
| ⅳ | レプリケーションルールの削除 | バケット削除前にレプリケーションルールを必ず削除しておく必要があります |
2. Jenkins
上記 Lambda ⅳ の実行をラップしつつ、バケットの完全削除までを行うパイプラインです
機能:
- Lambda④を実行し、レプリケーション設定を削除
-
delete_bucketを実行してバケットを削除 - 実行結果(成功/失敗)をSlack通知
▌さいごに
LambdaやJenkinsの権限設定もS3の仕様も全然分かっていなかったので、信じられないほど時間がかかりました(辛)
私を指導していくださった先輩はもっと辛かったことでしょう。「え…?そこから…?」と言いたげな顔が目に浮かびます。
ロール設定でつまずき、テストケースの作成でつまずき、最後の最後にバージョニング理解の浅さで手戻りの発生。。。
先輩の見込み時間の10倍はかかっていたんじゃないでしょうか(白目)
■ S3バケット削除における教訓
- AWS CLIによるオブジェクト削除は同期処理になる: 非同期実行ができないため、大量データの削除はライフサイクルルールに任せる
- レプリケーションルールを理解する: バケットを消したければレプリケーションルールを先に削除しないと手詰まる
- S3の処理にはバージョニング理解が超重要: 「現行バージョン」と「非現行バージョン」の全てを削除しないとバケットは「空」の状態にならない
- ライフサイクルルールは即時適用できない: ライフサイクルルールの初回実行は設定後から最も近いUTC0時(JST9時)。初めて動いたのが確認できるのは1〜2日後
- デシジョンテーブルの作成: 大事なのはテスト設計。それがほぼすべて
■スペシャルサンクス
先輩
ここまで見放さず丁寧に面倒を見てくださり誠にありがとうございました。(大感謝)
同じようなバケット削除問題に直面している方の一助となれば幸いです!
最後まで読んでいただきありがとうございました 🌸
もっと他の記事も読んでみたい方
当社に興味がある方はこちら👀