Lambdaを使用して削除マーカーを一括削除する(一括復元方法)

Lambdaを使用して削除マーカーを一括削除する(一括復元方法)

はじめに

こんにちは、パオの人ことさすけです!
S3 のオブジェクトをライフサイクルルールを利用するなどして、一括削除すると「間違って消すつもりのないプレフィックス(フォルダやオブジェクトなど)を削除しちゃった!!」なんてことありますよね。

バージョニングが有効かされているバケットの場合、削除マーカーを削除すれば復元できるわけですが、大量に削除していた場合ひとつひとつこの作業を行うのは大変。。。

そんな時、Lambda を使用して「プレフィックスを指定した削除マーカーの削除」を行ってみましょうというブログになります!

テスト用バケット

今回はテスト用に test-pao-pk10 というバケットを作成し、その中に削除済みのフォルダおよびフォルダ内のオブジェクトを用意しました。
フォルダ名は pao です。

image-29

Lambda 関数

さて、早速 Lambda 関数を作成します。
今回はランタイムを Python3.13 として、関数を作成。その後、コードに以下をペーストしてデプロイします。

また、オブジェクトの量に応じて時間がかかる場合があるので、Lambda のタイムアウト設定を適当に設定しておきましょう。(今回は 10 秒にしておきましたが、適宜変更してください)
タイムアウト設定の変更に関しては、「設定」タブ→「一般設定」から変更することができます。

import boto3

def lambda_handler(event, context):
    bucket_name = "test-pao-pk10"    # バケット名
    prefix = "pao/"     # プレフィックス

    s3 = boto3.client("s3")

    deletion_markers_deleted = 0

    # ページネーション対応のための初期パラメータ
    kwargs = {
        "Bucket": bucket_name,
        "Prefix": prefix,
    }

    while True:
        try:
            response = s3.list_object_versions(**kwargs)
        except Exception as e:
            print(f"Error listing object versions: {str(e)}")
            raise e

        # 削除マーカーのリストを取得(存在しない場合もあるので get で)
        deletion_markers = response.get("DeleteMarkers", [])

        for marker in deletion_markers:
            key = marker["Key"]
            version_id = marker["VersionId"]
            try:
                # s3.delete_object で削除マーカーを削除
                s3.delete_object(Bucket=bucket_name, Key=key, VersionId=version_id)
                deletion_markers_deleted += 1
                print(f"Deleted deletion marker: Key={key} VersionId={version_id}")
            except Exception as e:
                print(f"Error deleting deletion marker for Key={key}, VersionId={version_id}: {str(e)}")

        # ページネーション判定
        if response.get("IsTruncated"):
            # 次のページを取得するためのパラメータが返されるので、それを kwargs に追加
            kwargs["KeyMarker"] = response.get("NextKeyMarker")
            kwargs["VersionIdMarker"] = response.get("NextVersionIdMarker")
        else:
            break

    return {
        "statusCode": 200,
        "body": f"Deleted {deletion_markers_deleted} deletion markers."
    }

Lambda 実行ロール

さて、Lambda の実行ロールに権限を追加します。
Lambda 関数内の、「設定」タブ→「アクセス権限」と進み、ロール名のリンクをクリックすると実行ロールにアクセスすることができます。

権限としては、s3:DeleteObjectVersions3:ListBucketVersions が必要なので、以下のものアタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObjectVersion",
                "s3:ListBucketVersions"
            ],
            "Resource": [
                "arn:aws:s3:::test-pao-pk10",
                "arn:aws:s3:::test-pao-pk10/*"
            ]
        }
    ]
}

Lambda を実行してみる

さぁ、準備は整ったので実際に実行してみましょう!
「テスト」ボタンを押して実行してみます。上手くいくと以下のようなレスポンスが返ってきます。

{
  "statusCode": 200,
  "body": "Deleted 4 deletion markers."
}

実際に test-pao-pk10 バケットを確認してみると、画像の通り現行バージョンとして pao フォルダおよびその中身が復元されていました。

image-31

まとめ

さて、今回は削除マーカーの一括削除を行って、複数のオブジェクトを復元してみました。
削除時のプレフィックス指定ミスなど、割と起こりうる事象だと思いますので、もし気が向いたら事前に検証しておくと安心かもしれません。

アノテーション株式会社

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.