Skip to content

Commit

Permalink
Merge pull request #11795 from camlow325/retry_put_bucket_encryption_…
Browse files Browse the repository at this point in the history
…for_409_conflict

resource/aws_s3_bucket: Retry on PutBucketEncryption 409 Errors
  • Loading branch information
ewbankkit authored Aug 27, 2021
2 parents 8166877 + 26dbbbd commit 6239d0e
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .changelog/11795.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_s3_bucket: Retry on `PutBucketEncryption` HTTP 409 errors due to eventual consistency
```
27 changes: 27 additions & 0 deletions aws/internal/service/s3/enum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package s3

import (
"github.com/aws/aws-sdk-go/service/s3"
)

// These should be defined in the AWS SDK for Go. There is an open issue https://github.com/aws/aws-sdk-go/issues/2683
const (
BucketCannedACLAwsExecRead = "aws-exec-read"
BucketCannedACLLogDeliveryWrite = "log-delivery-write"
)

func BucketCannedACL_Values() []string {
result := s3.BucketCannedACL_Values()
result = appendUniqueString(result, BucketCannedACLAwsExecRead)
result = appendUniqueString(result, BucketCannedACLLogDeliveryWrite)
return result
}

func appendUniqueString(slice []string, elem string) []string {
for _, e := range slice {
if e == elem {
return slice
}
}
return append(slice, elem)
}
1 change: 1 addition & 0 deletions aws/internal/service/s3/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ const (
ErrCodeNoSuchConfiguration = "NoSuchConfiguration"
ErrCodeNoSuchPublicAccessBlockConfiguration = "NoSuchPublicAccessBlockConfiguration"
ErrCodeNoSuchTagSet = "NoSuchTagSet"
ErrCodeOperationAborted = "OperationAborted"
)
13 changes: 11 additions & 2 deletions aws/internal/service/s3/waiter/waiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@ package waiter

import (
"time"

"github.com/aws/aws-sdk-go/service/s3"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

const (
// Maximum amount of time to wait for S3 changes to propagate
PropagationTimeout = 1 * time.Minute
BucketCreatedTimeout = 2 * time.Minute
PropagationTimeout = 1 * time.Minute
)

// RetryWhenBucketNotFound retries the specified function if the returned error indicates that a bucket is not found.
// If the retries time out the specified function is called one last time.
func RetryWhenBucketNotFound(f func() (interface{}, error)) (interface{}, error) {
return tfresource.RetryWhenAwsErrCodeEquals(PropagationTimeout, f, s3.ErrCodeNoSuchBucket)
}
33 changes: 13 additions & 20 deletions aws/resource_aws_s3_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,11 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/hashcode"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
tfs3 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/s3"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/s3/waiter"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

const s3BucketCreationTimeout = 2 * time.Minute

// These should be defined in the AWS SDK for Go. There is an open issue https://github.com/aws/aws-sdk-go/issues/2683
const (
BucketCannedACLAwsExecRead = "aws-exec-read"
BucketCannedACLLogDeliveryWrite = "log-delivery-write"
)

func BucketCannedACL_Values() []string {
result := s3.BucketCannedACL_Values()
result = appendUniqueString(result, BucketCannedACLAwsExecRead)
result = appendUniqueString(result, BucketCannedACLLogDeliveryWrite)
return result
}

func resourceAwsS3Bucket() *schema.Resource {
return &schema.Resource{
Create: resourceAwsS3BucketCreate,
Expand Down Expand Up @@ -92,7 +79,7 @@ func resourceAwsS3Bucket() *schema.Resource {
Default: "private",
Optional: true,
ConflictsWith: []string{"grant"},
ValidateFunc: validation.StringInSlice(BucketCannedACL_Values(), false),
ValidateFunc: validation.StringInSlice(tfs3.BucketCannedACL_Values(), false),
},

"grant": {
Expand Down Expand Up @@ -817,7 +804,7 @@ func resourceAwsS3BucketRead(d *schema.ResourceData, meta interface{}) error {
Bucket: aws.String(d.Id()),
}

err := resource.Retry(s3BucketCreationTimeout, func() *resource.RetryError {
err := resource.Retry(waiter.BucketCreatedTimeout, func() *resource.RetryError {
_, err := s3conn.HeadBucket(input)

if d.IsNewResource() && tfawserr.ErrStatusCodeEquals(err, http.StatusNotFound) {
Expand Down Expand Up @@ -1970,9 +1957,15 @@ func resourceAwsS3BucketServerSideEncryptionConfigurationUpdate(s3conn *s3.S3, d
}
log.Printf("[DEBUG] S3 put bucket replication configuration: %#v", i)

_, err := retryOnAwsCode(s3.ErrCodeNoSuchBucket, func() (interface{}, error) {
return s3conn.PutBucketEncryption(i)
})
_, err := tfresource.RetryWhenAwsErrCodeEquals(
waiter.PropagationTimeout,
func() (interface{}, error) {
return s3conn.PutBucketEncryption(i)
},
s3.ErrCodeNoSuchBucket,
tfs3.ErrCodeOperationAborted,
)

if err != nil {
return fmt.Errorf("error putting S3 server side encryption configuration: %s", err)
}
Expand Down
9 changes: 0 additions & 9 deletions aws/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,6 @@ func isResourceTimeoutError(err error) bool {
return tfresource.TimedOut(err)
}

func appendUniqueString(slice []string, elem string) []string {
for _, e := range slice {
if e == elem {
return slice
}
}
return append(slice, elem)
}

func StringSlicesEqualIgnoreOrder(s1, s2 []*string) bool {
if len(s1) != len(s2) {
return false
Expand Down

0 comments on commit 6239d0e

Please sign in to comment.