💬

【S3バッチオペレーション活用!】S3バケット特定フォルダ以下のオブジェクト一括削除

2025/01/24に公開

はじめに

S3バケットにおいて、このフォルダ以下のオブジェクトを全部削除したいと思ったことはないでしょうか。

数が少なければ手動やCLIで削除すればいいけど、大量にあるとライフサイクルで一括削除が望ましいですよね。(CLIでひとつひとつ削除を自動化してもだいぶ時間がかかります…)

しかし、S3ライフサイクルでは、プレフィックスにアスタリスク(*)の正規表現を使用して対象を指定することはできません。

(↓これでtestフォルダ以下一括指定とかできない…)

そのため、
「このフォルダ以下だけ削除したい」という要件をライフサイクルで直接実現
することは難しいです。

この記事では、ライフサイクルをつかって特定のフォルダ以下のオブジェクトを一括削除する手順を紹介します。

結論

S3バッチオペレーションを使用して削除対象のオブジェクトにタグを一括付与し、そのタグを条件にしたライフサイクルを設定する方法を実行します。この仕組みを使えば、フォルダ配下のファイルのみを削除できます。

バッチオペレーションとは?

バッチオペレーションは、AWS S3のオブジェクトに対して一括で操作を実行するための機能です。通常、S3のオブジェクトに対する操作は1つずつ手動で行う必要がありますが、バッチオペレーションを使用することで、複数のオブジェクトに対して一度に操作を適用できます。

https://aws.amazon.com/jp/s3/features/batch-operations/


作業の流れ

大まかな流れとしてはこちらです。

  1. マニフェストファイル作成
  2. バッチオペレーション実行
  3. ライフサイクル設定

以下にそれぞれの詳細を記載していきます。

1. マニフェストファイル作成

バッチオペレーションは、マニフェストファイル(CSV形式のファイル)を使用して、操作対象のオブジェクトを指定します。

今回は一括削除がしたいため、削除対象をすべて一覧化したcsvファイルがマニフェストファイルになります。
マニフェストには、各オブジェクトのバケット名、オブジェクトキーを含める必要があります。

※AWSのドキュメントに記載の例。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/batch-ops-create-job.html#specify-batchjob-manifest

そんなのどう作るの?って思いますが、S3インベントリとAthenaを使いちょっとだけ頑張って作成します。

マニフェストファイル作成の流れ

  1. S3インベントリレポート出力用S3バケットの作成
  2. S3インベントリ設定の有効化(※最大48時間後にレポート出力)
  3. Athena テーブルを作成
  4. Athena 削除対象オブジェクト一覧取得クエリ実行
  5. csvファイルの取得/加工

1. インベントリレポート出力用S3バケットの作成

既存のバケットを使用することもできますが、ここではレポート出力用バケットを新規に作成します。

レポート用S3バケットは特に特別な設定は不要なので、すべてデフォルト値での作成で問題ありません。

2, インベントリ設定の有効化

対象のS3バケットに対してインベントリを有効化します。
AWSマネージドコンソールより対象S3バケットに移動し、"管理"タブから"インベントリ設定"の作成を押下します。

次に、インベントリの各設定です。
頻度、出力形式、追加のメタデータフィールドを以下の設定にします。

設定項目
頻度 日別
出力形式 Apache Parquet

それ以外の設定は任意の設定を入力してください。設定値を選択する箇所はデフォルトの設定で問題ありません。

設定後48時間以内に、指定のS3バケットのインベントリ名/hiveフォルダ以下にレポートが出力されます。

3. Athena テーブルを作成

Athenaで任意のデータベースを選択し、テーブル作成クエリを実行します。
クエリの内容はこちらです。

CREATE EXTERNAL TABLE table_name(
         bucket string,
         key string
) PARTITIONED BY (
        dt string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
  STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat'
  OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat'
  LOCATION 's3://[S3バケット名]/[インベントリ名]/hive/'
  TBLPROPERTIES (
    "projection.enabled" = "true",
    "projection.dt.type" = "date",
    "projection.dt.format" = "yyyy-MM-dd-HH-mm",
    "projection.dt.range" = "2024-02-01-01-00,NOW",
    "projection.dt.interval" = "1",
    "projection.dt.interval.unit" = "HOURS"
  );
"projection.dt.range" = "2024-02-01-01-00,NOW",

4. Athena 削除対象オブジェクト一覧取得クエリ実行

テーブルが作成後、削除対象オブジェクト一覧取得クエリ実行します。

select bucket,key from table_name WHERE key LIKE 'test/';

今回はtestフォルダ以下をすべて削除するため、このSQL文になっていますが、削除対象に応じて柔軟に変更してください。

5. csvファイルの取得/加工

[結果をダウンロード]をクリックしてcsvファイルをダウンロードします。

ダウンロードしたcsvファイルを開き、マニフェストファイル用に一行目を削除します。

これでマニフェストファイルが完成です!

2. バッチオペレーション実行

バッチオペレーションで削除対象のオブジェクトにタグを付けます。

マニフェスト作成全体の流れ

  1. マニフェストファイル用S3バケットの作成/アップロード
  2. バッチオペレーションジョブ用IAMロール作成
  3. バッチオペレーションジョブ作成
  4. バッチオペレーションジョブ実行

1. マニフェストファイル用S3バケットの作成/アップロード

S3バケットを新規作成し、Athenaで前項で準備したマニフェストファイルをアップロードします。
ここでは特に特別な設定はないため、S3はデフォルト設定で問題ありません。

2. バッチオペレーションジョブ用IAMロール作成

必要なS3アクセス権限を持つIAMロールを作成します。
(検証時はS3のフルアクセスポリシーをアタッチしたロールを作成しました)

3. バッチオペレーションジョブ作成

AWSコンソールから S3 -> バッチオペレーション -> ジョブの作成 に遷移します。

マニフェスト形式にcsvを指定、S3にアップロードしたマニフェストファイルを選択し[次へ]を押下。

すべてのオブジェクトタグを置換するを選択し、任意のタグを指定し[次へ]を押下。

作成したIAMロールを指定。

※完了レポートは特に不要な場合はチェックを外してください。

確認ページに遷移して[ジョブの作成]を押下します。

一覧に作成したジョブが表示されます。

4. バッチオペレーションジョブ実行

作成したジョブを実行します。

実行中は、ステータスにタグ付けに成功(失敗)した数がリアルタイムにカウントされていきます。
※約2,800万オブジェクトに対して実行した際は、完了まで10時間ほどかかりました。
(↓58%完了辞典で5時間ほど経過している)

ジョブが完了したら、マニフェストファイルにあるオブジェクトのすべてにタグ付けがされているはずです。

3. ライフサイクル設定

タグ付けが完了したら、後はS3ライフサイクルを設定するのみです。

対象S3バケットの 管理 -> ライフサイクルルールを作成する からライフサイクルを作成してください。

バッチオペレーションで付与したタグを指定します。

オブジェクトの現行バージョンを有効期限切れにするを選択して[ルールの作成]を押下。

※バージョニングが有効化されている場合は非現行バージョンの設定も追加してください。

これで以上です。
ライフサイクルの反映には最大3日ほどかかるため、数日後に削除されていることを確認し作業完了です。


まとめ

この手順を使用すると、特定フォルダ配下のS3オブジェクトを効率的に削除できます。
また、Athenaでのクエリを工夫すれば、さまざまな条件に基づいたタグ付けが可能となり、他の要件にも応用可能です。

We're Hiring!

DELTAではチームの一員になっていただける仲間を募集中です!
下記フォームよりお気軽にご連絡ください!

https://docs.google.com/forms/d/e/1FAIpQLSfQuWNU1il5lq2rVdICM0tSK_jTsjqwc52LYEwUxBq7_ImtrQ/viewform

Discussion