【AWS】CLIからバージョニングされたS3バケットを削除する方法
S3バケットは空にしてからでないと削除できません。それはバージョニングされたバケットでも同様です。
問題は、バージョニングされたオブジェクトを削除しても、実は消えていないことです。DeleteMarkerが追加されるだけで、オブジェクトが完全に消えるわけではありません。完全に削除するためには、DeleteMarkerとバージョンも削除する必要があります。
マネージメントコンソールであれば削除するのは難しくありません。しかし、AWS CLIから少々面倒なので手順をまとめました。
[1] オブジェクトの削除
[1-1] バケットとファイルの作成
試しにバージョニングされたバケットを作成し、test.txtをアップロードします。
$ aws s3 ls s3://{バケット名} 2021-04-17 13:19:12 4 test.txt
バージョンを確認します。
$ aws s3api list-object-versions --bucket {バケット名} { "Versions": [ { "LastModified": "2021-04-17T13:19:12.000Z", "VersionId": "Goie_timWFWXJTwHv9swGAyjbIrDI6cQ", "ETag": "\"033bd94b1168d7e4f0d644c3c95e35bf\"", "StorageClass": "STANDARD", "Key": "test.txt", "Owner": { "DisplayName": "{所有者の表示名}", "ID": "{所有者のID}" }, "IsLatest": true, "Size": 4 } ] }
[1-2] オブジェクトの削除
aws s3 rm
でオブジェクトを削除します。
$ aws s3 rm s3://{バケット名}/ --recursive delete: s3://{バケット名}/test.txt
aws s3 ls
で確認すると削除されたように見えます。
$ aws s3 ls s3://{バケット名}
しかし、バケットを削除しようとするとエラーが発生します。
$ aws s3 rb s3://{バケット名} --force remove_bucket failed: s3://{バケット名} An error occurred (BucketNotEmpty) when calling the DeleteBucket operation: The bucket you tried to delete is not empty. You must delete all versions in the bucket.
[1-3] バージョンの確認
バージョンを確認すると、完全には削除されていないことが分かります。DeleteMarkersが追加されています。
$ aws s3api list-object-versions --bucket {バケット名} { "DeleteMarkers": [ { "Owner": { "DisplayName": "{所有者の表示名}", "ID": "{所有者のID}" }, "IsLatest": true, "VersionId": "mfYZIOM57MlB_8BkvG7YcNuKWJz0geHS", "Key": "test.txt", "LastModified": "2021-04-17T13:35:10.000Z" } ], "Versions": [ { "LastModified": "2021-04-17T13:19:12.000Z", "VersionId": "Goie_timWFWXJTwHv9swGAyjbIrDI6cQ", "ETag": "\"033bd94b1168d7e4f0d644c3c95e35bf\"", "StorageClass": "STANDARD", "Key": "test.txt", "Owner": { "DisplayName": "{所有者の表示名}", "ID": "{所有者のID}" }, "IsLatest": false, "Size": 4 } ] }
"DeleteMarkers", "Versions"を削除する必要があります。
[2] 完全な削除
以下のシェルスクリプトを作成・実行して削除します。コマンドは下記記事を参考にさせていただきました。
バージョニングが有効なS3バケットをAWS CLIで空にする手順(オブジェクト1000個以下) - のぴぴのメモ
#!/bin/bash BUCKET_NAME={バケット名} # バケット内の全オブジェクト削除 aws s3 rm s3://${BUCKET_NAME}/ --recursive # DeleteMarkersの削除 aws s3api list-object-versions --bucket ${BUCKET_NAME} \ | jq -r -c '.["DeleteMarkers"][] | [.Key,.VersionId]' \ | while read line do key=`echo $line | jq -r .[0]` versionid=`echo $line | jq -r .[1]` aws s3api delete-object --bucket ${BUCKET_NAME} \ --key ${key} --version-id ${versionid} done # Versionsの削除 aws s3api list-object-versions --bucket ${BUCKET_NAME} \ | jq -r -c '.["Versions"][] | [.Key,.VersionId]' \ | while read line do key=`echo $line | jq -r .[0]` versionid=`echo $line | jq -r .[1]` aws s3api delete-object --bucket ${BUCKET_NAME} \ --key ${key} --version-id ${versionid} done
実行すると、以下のような結果が返ってきます。
$ sh delete_s3_object.sh { "VersionId": "mfYZIOM57MlB_8BkvG7YcNuKWJz0geHS", "DeleteMarker": true } { "VersionId": "Goie_timWFWXJTwHv9swGAyjbIrDI6cQ" }
バージョンを再度確認すると、今度は削除されています。
$ aws s3api list-object-versions --bucket {バケット名}
バケット削除を実行すると今度は削除に成功します。
$ aws s3 rb s3://{バケット名} --force remove_bucket: {バケット名}