web-dev-qa-db-ja.com

CLIを使用してAWS S3でバージョン管理されたバケットを削除するにはどうすればよいですか?

両方試してみましたs3cmd

$ s3cmd -r -f -v del s3://my-versioned-bucket/

そして、AWS CLI:

$ aws s3 rm s3://my-versioned-bucket/ --recursive

ただし、これらのコマンドはどちらもDELETEマーカーをS3に追加するだけです。バケットを削除するコマンドも機能しません(AWS CLIから):

$ aws s3 rb s3://my-versioned-bucket/ --force
Cleaning up. Please wait...
Completed 1 part(s) with ... file(s) remaining
remove_bucket failed: s3://my-versioned-bucket/ A client error (BucketNotEmpty) occurred when calling the DeleteBucket operation: The bucket you tried to delete is not empty. You must delete all versions in the bucket.

わかりました...どうやって?このための ドキュメント には情報がありません。 S3Cmdは、「完全な機能を備えた」S3コマンドラインツールであると言いますが、 バージョンへの参照なし 独自のものではありません。 Webインターフェイスを使用せずにこれを行う方法はありますか?これには永遠に時間がかかり、ラップトップをオンにしておく必要がありますか?

35
NobleUplift

それを行う1つの方法は、バージョンを反復処理して削除することです。 CLIには少し注意が必要ですが、Javaについて述べたように、それはより簡単です。

AmazonS3Client s3 = new AmazonS3Client();
String bucketName = "deleteversions-"+UUID.randomUUID();

//Creates Bucket
s3.createBucket(bucketName);

//Enable Versioning
BucketVersioningConfiguration configuration = new BucketVersioningConfiguration(ENABLED);
s3.setBucketVersioningConfiguration(new SetBucketVersioningConfigurationRequest(bucketName, configuration ));

//Puts versions
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("some-bytes".getBytes()), null);
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("other-bytes".getBytes()), null);

//Removes all versions
for ( S3VersionSummary version : S3Versions.inBucket(s3, bucketName) ) {
    String key = version.getKey();
    String versionId = version.getVersionId();          
    s3.deleteVersion(bucketName, key, versionId);
}

//Removes the bucket
s3.deleteBucket(bucketName);
System.out.println("Done!");

必要に応じて、効率のために呼び出しをバッチ削除することもできます。

4
faermanj

AWS CLIの同じ制限に遭遇しました。 Python and boto :を使用するのが最も簡単な解決策であることがわかりました。

#!/usr/bin/env python

BUCKET = 'your-bucket-here'

import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket(BUCKET)
bucket.object_versions.delete()

# if you want to delete the now-empty bucket as well, uncomment this line:
#bucket.delete()

この回答の以前のバージョンでは boto を使用していましたが、Chucklesが指摘したように、このソリューションには多数のキーでパフォーマンスの問題がありました。

36
Abe Voelker

boto3を使用すると、提案されたbotoソリューションを使用するよりも簡単に、S3バケット内のすべてのオブジェクトバージョンを削除できます。

#!/usr/bin/env python
import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('your-bucket-name')
bucket.object_versions.all().delete()

非常に大量のオブジェクトバージョンでも正常に動作しますが、その場合は時間がかかる場合があります。

17
Dunedan

バージョン管理されたs3バケット内のすべてのオブジェクトを削除できます。しかし、特定のオブジェクトを削除する方法がわかりません。

$ aws s3api delete-objects \
      --bucket <value> \
      --delete "$(aws s3api list-object-versions \
      --bucket <value> | \
      jq '{Objects: [.Versions[] | {Key:.Key, VersionId : .VersionId}], Quiet: false}')"

または、jqなし:

$ aws s3api delete-objects \
    --bucket ${bucket_name} \
    --delete "$(aws s3api list-object-versions \
    --bucket "${bucket_name}" \
    --output=json \
    --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
11
Cheers

コマンドラインにカットアンドペーストしてすべてのバージョンを削除し、マーカーを削除することができる1つのライナーを次に示します(awsツールが必要です。yourbucket-name-backupをバケット名に置き換えます)

echo '#!/bin/bash' > deleteBucketScript.sh \
&& aws --output text s3api list-object-versions --bucket $BUCKET_TO_PERGE \
| grep -E "^VERSIONS" |\
awk '{print "aws s3api delete-object --bucket $BUCKET_TO_PERGE --key "$4" --version-id "$8";"}' >> \
deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh; echo '#!/bin/bash' > \
deleteBucketScript.sh && aws --output text s3api list-object-versions --bucket $BUCKET_TO_PERGE \
| grep -E "^DELETEMARKERS" | grep -v "null" \
| awk '{print "aws s3api delete-object --bucket $BUCKET_TO_PERGE --key "$3" --version-id "$5";"}' >> \
deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh;

次に使用できます:

aws s3 rb s3://bucket-name --force

5
Nitin

list_bucketsジェネレーターを使用してall_keysと呼ばれる大規模なリストを作成するときに Abeのソリューション で問題が発生し、完了しないまま1時間を費やしました。このTweakは、私にとってはうまく機能しているようです。バケツに数えられるオブジェクトが100万個近くありました。

import boto

s3 = boto.connect_s3()
bucket = s3.get_bucket("your-bucket-name-here")

chunk_counter = 0 #this is simply a Nice to have
keys = []
for key in bucket.list_versions():
    keys.append(key)
    if len(keys) > 1000:
        bucket.delete_keys(keys)
        chunk_counter += 1
        keys = []
        print("Another 1000 done.... {n} chunks so far".format(n=chunk_counter))

#bucket.delete() #as per usual uncomment if you're sure!

これが、このS3の悪夢に遭遇する他の人を助けることを願っています!

4
chuckwired
  1. 削除するには、jqフィルターを使用してオブジェクトを指定します。
  2. 「バージョン」だけでなく「DeleteMarkers」のクリーンアップが必要になる場合があります。
  3. _``_の代わりに$()を使用すると、bucket-nameおよびkey-valueの変数を埋め込むことができます。
_aws s3api delete-objects --bucket bucket-name --delete "$(aws s3api list-object-versions --bucket bucket-name | jq -M '{Objects: [.["Versions","DeleteMarkers"][]|select(.Key == "key-value")| {Key:.Key, VersionId : .VersionId}], Quiet: false}')"
_
4
Tiger peng

https://Gist.github.com/wknapik/191619bfa650b8572115cd07197f3baf

#!/usr/bin/env bash

set -eEo pipefail
shopt -s inherit_errexit >/dev/null 2>&1 || true

if [[ ! "$#" -eq 2 || "$1" != --bucket ]]; then
    echo -e "USAGE: $(basename "$0") --bucket <bucket>"
    exit 2
fi

# $@ := bucket_name
empty_bucket() {
    local -r bucket="${1:?}"
    for object_type in Versions DeleteMarkers; do
        local opt=() next_token=""
        while [[ "$next_token" != null ]]; do
            page="$(aws s3api list-object-versions --bucket "$bucket" --output json --max-items 1000 "${opt[@]}" \
                        --query="[{Objects: ${object_type}[].{Key:Key, VersionId:VersionId}}, NextToken]")"
            objects="$(jq -r '.[0]' <<<"$page")"
            next_token="$(jq -r '.[1]' <<<"$page")"
            case "$(jq -r .Objects <<<"$objects")" in
                '[]'|null) break;;
                *) opt=(--starting-token "$next_token")
                   aws s3api delete-objects --bucket "$bucket" --delete "$objects";;
            esac
        done
    done
}

empty_bucket "${2#s3://}"

例えば。 empty_bucket.sh --bucket foo

これにより、すべてのオブジェクトバージョンが削除され、バケット内のマーカーが1000のバッチで削除されます。その後、aws s3 rb s3://fooを使用してバケットを削除できます。

Bash、awscli、jqが必要です。

0
user2402169

私が見つけた最も簡単な方法は、このCLIツールs3wipeを使用することです。 Dockerコンテナとして提供されているため、次のように使用できます。

$ docker run -it --rm slmingol/s3wipe --help
usage: s3wipe [-h] --path PATH [--id ID] [--key KEY] [--dryrun] [--quiet]
              [--batchsize BATCHSIZE] [--maxqueue MAXQUEUE]
              [--maxthreads MAXTHREADS] [--delbucket] [--region REGION]

Recursively delete all keys in an S3 path

optional arguments:
  -h, --help               show this help message and exit
  --path PATH              S3 path to delete (e.g. s3://bucket/path)
  --id ID                  Your AWS access key ID
  --key KEY                Your AWS secret access key
  --dryrun                 Don't delete. Print what we would have deleted
  --quiet                  Suprress all non-error output
  --batchsize BATCHSIZE    # of keys to batch delete (default 100)
  --maxqueue MAXQUEUE      Max size of deletion queue (default 10k)
  --maxthreads MAXTHREADS  Max number of threads (default 100)
  --delbucket              If S3 path is a bucket path, delete the bucket also
  --region REGION          Region of target S3 bucket. Default vaue `us-
                           east-1`

バケット内のすべてのバージョン付きオブジェクトを削除してからバケットを削除する例を次に示します。

$ docker run -it --rm slmingol/s3wipe \
   --id $(aws configure get default.aws_access_key_id) \
   --key $(aws configure get default.aws_secret_access_key) \
   --path s3://bw-tf-backends-aws-example-logs \
   --delbucket
[2019-02-20@03:39:16] INFO: Deleting from bucket: bw-tf-backends-aws-example-logs, path: None
[2019-02-20@03:39:16] INFO: Getting subdirs to feed to list threads
[2019-02-20@03:39:18] INFO: Done deleting keys
[2019-02-20@03:39:18] INFO: Bucket is empty.  Attempting to remove bucket

使い方

ここで少し解凍する必要がありますが、上記は次のことをしています:

  • docker run -it --rm mikelorant/s3wipe-s3wipeコンテナをインタラクティブに実行し、実行のたびに削除します
  • --id--key-アクセスキーとアクセスIDを渡す
  • aws configure get default.aws_access_key_id-キーIDを取得します
  • aws configure get default.aws_secret_access_key-キーシークレットを取得します
  • --path s3://bw-tf-backends-aws-example-logs-削除するバケット
  • --delbucket-空になったらバケットを削除します

参照資料

0
slm

ここにあるこのbashスクリプト: https://Gist.github.com/weavenet/f40b09847ac17dd99d16

私のためにそのまま働いた。

スクリプトをdelete_all_versions.shとして保存してから、単に実行しました。

./delete_all_versions.sh my_foobar_bucket

そしてそれは欠陥なしで働きました。

pythonまたはbotoなど何も必要ありませんでした。

0
Mamun