From 2c34a4213466f06ad9b0b4bb63bb3a1ef68e4575 Mon Sep 17 00:00:00 2001 From: Jeremy Barlow Date: Fri, 24 Apr 2020 11:44:39 -0600 Subject: [PATCH] resource/aws_s3_bucket: Retry on GetBucketTagging 404 Errors References: * https://github.com/terraform-providers/terraform-provider-aws/issues/13008 The AWS S3 service has eventual consistency considerations. If a GetBucketTagging call is made to obtain tags just after an S3 bucket is first created, AWS may return an HTTP 404 (NotFound) error with a NoSuchBucket error code. A fix was added for this in #12418. It appears that the NoSuchBucket errors are not retried with this fix, however. This commit adds some extra logic which ensures that the code from the awserr.Error instance is evaluated for retry. Output for acceptance testing: ``` > make testacc TEST=./aws TESTARGS='-run=TestAccAWSS3Bucket_' ... --- PASS: TestAccAWSS3Bucket_shouldFailNotFound (22.93s) --- PASS: TestAccAWSS3Bucket_LifecycleRule_Expiration_EmptyConfigurationBlock (38.71s) --- PASS: TestAccAWSS3Bucket_forceDestroyWithEmptyPrefixes (40.46s) --- PASS: TestAccAWSS3Bucket_forceDestroy (40.47s) --- PASS: TestAccAWSS3Bucket_enableDefaultEncryption_whenAES256IsUsed (45.72s) --- PASS: TestAccAWSS3Bucket_basic (45.79s) --- PASS: TestAccAWSS3Bucket_forceDestroyWithObjectLockEnabled (47.59s) --- PASS: TestAccAWSS3Bucket_ReplicationExpectVersioningValidationError (51.85s) --- PASS: TestAccAWSS3Bucket_LifecycleBasic (95.95s) --- PASS: TestAccAWSS3Bucket_LifecycleExpireMarkerOnly (69.16s) --- PASS: TestAccAWSS3Bucket_enableDefaultEncryption_whenTypical (71.63s) --- PASS: TestAccAWSS3Bucket_objectLock (74.52s) --- PASS: TestAccAWSS3Bucket_disableDefaultEncryption_whenDefaultEncryptionIsEnabled (75.75s) --- PASS: TestAccAWSS3Bucket_region (42.47s) --- PASS: TestAccAWSS3Bucket_ReplicationWithoutPrefix (96.80s) --- PASS: TestAccAWSS3Bucket_WebsiteRoutingRules (77.87s) --- PASS: TestAccAWSS3Bucket_Versioning (106.51s) --- PASS: TestAccAWSS3Bucket_UpdateGrant (110.50s) --- PASS: TestAccAWSS3Bucket_GrantToAcl (71.89s) --- PASS: TestAccAWSS3Bucket_AclToGrant (72.06s) --- PASS: TestAccAWSS3Bucket_generatedName (47.42s) --- PASS: TestAccAWSS3Bucket_UpdateAcl (74.86s) --- PASS: TestAccAWSS3Bucket_namePrefix (44.58s) --- PASS: TestAccAWSS3Bucket_RequestPayer (75.62s) --- PASS: TestAccAWSS3Bucket_ReplicationWithoutStorageClass (97.00s) --- PASS: TestAccAWSS3Bucket_Cors_EmptyOrigin (47.36s) --- PASS: TestAccAWSS3Bucket_WebsiteRedirect (109.43s) --- PASS: TestAccAWSS3Bucket_Website_Simple (109.41s) --- PASS: TestAccAWSS3Bucket_ReplicationConfiguration_Rule_Destination_AddAccessControlTranslation (152.76s) --- PASS: TestAccAWSS3Bucket_acceleration (81.59s) --- PASS: TestAccAWSS3Bucket_Cors_Delete (36.58s) --- PASS: TestAccAWSS3Bucket_Bucket_EmptyString (44.94s) --- PASS: TestAccAWSS3Bucket_Logging (66.26s) --- PASS: TestAccAWSS3Bucket_Policy (104.79s) --- PASS: TestAccAWSS3Bucket_ReplicationConfiguration_Rule_Destination_AccessControlTranslation (176.75s) --- PASS: TestAccAWSS3Bucket_Cors_Update (71.71s) --- PASS: TestAccAWSS3Bucket_tagsWithNoSystemTags (135.94s) --- PASS: TestAccAWSS3Bucket_tagsWithSystemTags (168.39s) --- PASS: TestAccAWSS3Bucket_Replication (270.65s) --- PASS: TestAccAWSS3Bucket_ReplicationSchemaV2 (273.25s) ``` --- aws/awserr.go | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/aws/awserr.go b/aws/awserr.go index efe0553b72c..6df07f7bec1 100644 --- a/aws/awserr.go +++ b/aws/awserr.go @@ -1,10 +1,8 @@ package aws import ( - "errors" "time" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" @@ -38,31 +36,3 @@ func retryOnAwsCode(code string, f func() (interface{}, error)) (interface{}, er return resp, err } - -// RetryOnAwsCodes retries AWS error codes for one minute -// Note: This function will be moved out of the aws package in the future. -func RetryOnAwsCodes(codes []string, f func() (interface{}, error)) (interface{}, error) { - var resp interface{} - err := resource.Retry(1*time.Minute, func() *resource.RetryError { - var err error - resp, err = f() - if err != nil { - var awsErr awserr.Error - if errors.As(err, &awsErr) { - for _, code := range codes { - if awsErr.Code() == code { - return resource.RetryableError(err) - } - } - } - return resource.NonRetryableError(err) - } - return nil - }) - - if tfresource.TimedOut(err) { - resp, err = f() - } - - return resp, err -}