From 3d28b8dec227716eda962716cb0e315074d2b05b Mon Sep 17 00:00:00 2001 From: Piotr Komborski Date: Fri, 4 Dec 2015 15:10:26 +0000 Subject: [PATCH] S3 bucket force_destroy error: MalformedXML AWS provider was not checking whether DeleteMarkers are left in S3 bucket causing s3.DeleteObjectsInput to send empty XML which resulted in 400 error and MalformedXML message. --- .../providers/aws/resource_aws_s3_bucket.go | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/builtin/providers/aws/resource_aws_s3_bucket.go b/builtin/providers/aws/resource_aws_s3_bucket.go index 069cb837a..ec5745202 100644 --- a/builtin/providers/aws/resource_aws_s3_bucket.go +++ b/builtin/providers/aws/resource_aws_s3_bucket.go @@ -406,30 +406,46 @@ func resourceAwsS3BucketDelete(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] S3 Bucket attempting to forceDestroy %+v", err) bucket := d.Get("bucket").(string) - resp, err := s3conn.ListObjects( - &s3.ListObjectsInput{ + resp, err := s3conn.ListObjectVersions( + &s3.ListObjectVersionsInput{ Bucket: aws.String(bucket), }, ) if err != nil { - return fmt.Errorf("Error S3 Bucket list Objects err: %s", err) + return fmt.Errorf("Error S3 Bucket list Object Versions err: %s", err) } - objectsToDelete := make([]*s3.ObjectIdentifier, len(resp.Contents)) - for i, v := range resp.Contents { - objectsToDelete[i] = &s3.ObjectIdentifier{ - Key: v.Key, + objectsToDelete := make([]*s3.ObjectIdentifier, 0) + + if len(resp.DeleteMarkers) != 0 { + + for _, v := range resp.DeleteMarkers { + objectsToDelete = append(objectsToDelete, &s3.ObjectIdentifier{ + Key: v.Key, + VersionId: v.VersionId, + }) } } - _, err = s3conn.DeleteObjects( - &s3.DeleteObjectsInput{ - Bucket: aws.String(bucket), - Delete: &s3.Delete{ - Objects: objectsToDelete, - }, + + if len(resp.Versions) != 0 { + for _, v := range resp.Versions { + objectsToDelete = append(objectsToDelete, &s3.ObjectIdentifier{ + Key: v.Key, + VersionId: v.VersionId, + }) + } + } + + params := &s3.DeleteObjectsInput{ + Bucket: aws.String(bucket), + Delete: &s3.Delete{ + Objects: objectsToDelete, }, - ) + } + + _, err = s3conn.DeleteObjects(params) + if err != nil { return fmt.Errorf("Error S3 Bucket force_destroy error deleting: %s", err) }