¿Cómo elimino un bucket versionado en AWS S3 usando la CLI?


He intentado ambos s3cmd:

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

Y la CLI de AWS:

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

Pero ambos comandos simplemente agregan DELETE marcadores a S3. El comando para eliminar un bucket tampoco funciona (desde la CLI de AWS):

$ 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.

Ok... ¿Cómo? No hay información en su documentación para esto. S3Cmd dice que es una herramienta de línea de comandos S3 'con todas las funciones', pero no hace ninguna referencia a las versiones que no sean las suyas. ¿Hay alguna manera de hacer esto sin usar la web interfaz, que llevará una eternidad y requiere que mantenga mi computadora portátil encendida?

Author: NobleUplift, 2015-04-23

7 answers

Una forma de hacerlo es iterar a través de las versiones y eliminarlas. Un poco complicado en la CLI, pero como mencionaste Java, eso sería más sencillo:

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!");

También puede eliminar llamadas por lotes para obtener eficiencia si es necesario.

 3
Author: faermanj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-26 19:20:33

Me encontré con la misma limitación de la CLI de AWS. Encontré la solución más fácil de usar Python y boto3 :

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()

Una versión anterior de esta respuesta usaba boto pero esa solución tenía problemas de rendimiento con un gran número de teclas, como señaló Chuckles.

 24
Author: Abe Voelker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-18 04:40:19

Usando boto3 es aún más fácil que con la solución propuesta boto eliminar todas las versiones de objetos en un bucket S3:

#!/usr/bin/env python
import boto3

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

Funciona bien también para grandes cantidades de versiones de objetos, aunque podría tomar algún tiempo en ese caso.

 12
Author: Dunedan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-30 16:07:12

Puede eliminar todos los objetos del bucket s3 versionado. Pero no se como borrar objetos específicos. aws s3api delete-objects --bucket <value> --delete "$(aws s3api list-object-versions --bucket <value> | jq '{Objects: [.Versions[] | {Key:.Key, VersionId : .VersionId}], Quiet: false}')"

Espero que te sea útil.

 9
Author: Cheers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-11 06:56:40

Me encontré con problemas con solución de Abe como el generador list_buckets se utiliza para crear una lista masiva llamada all_keys y pasé una hora sin que se complete. Este ajuste parece funcionar mejor para mí, tenía cerca de un millón de objetos en mi cubo y contando!

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!

Esperemos que esto ayude a cualquier otra persona que se encuentre con esta pesadilla S3!

 5
Author: chuckwired,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:07
  1. Para eliminar especificar objeto(s), usando el filtro jq.
  2. Es posible que necesite limpiar los 'DeleteMarkers' no solo las 'Versiones'.
  3. Usando $() en lugar de ``, puede incrustar variables para bucket-name y 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
Author: Tiger peng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-05 20:08:05

Aquí hay un trazador de líneas que solo puede cortar y pegar en la línea de comandos para eliminar todas las versiones y eliminar marcadores (requiere aws tools, reemplace su copia de seguridad de nombre de cubo con su nombre de cubo)

echo '#!/bin/bash' > deleteBucketScript.sh && aws --output text s3api list-object-versions --bucket yourbucket-name-backup | grep -E "^VERSIONS" | awk '{print "aws s3api delete-object --bucket yourbucket-name-backup --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 yourbucket-name-backup | grep -E "^DELETEMARKERS" | grep -v "null" | awk '{print "aws s3api delete-object --bucket yourbucket-name-backup --key "$3" --version-id "$5";"}' >> deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh;

Entonces podrías usar:

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

 4
Author: Nitin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-22 11:30:51