diff --git a/.changelog/22610.txt b/.changelog/22610.txt new file mode 100644 index 00000000000..68d3781ffd9 --- /dev/null +++ b/.changelog/22610.txt @@ -0,0 +1,3 @@ +```release-note:breaking-change +resource/aws_s3_bucket: The `acceleration_status` argument has been deprecated and is now read-only. Use the `aws_s3_bucket_accelerate_configuration` resource instead. +``` \ No newline at end of file diff --git a/internal/service/s3/bucket.go b/internal/service/s3/bucket.go index 788ace936f7..c6d7d1f7060 100644 --- a/internal/service/s3/bucket.go +++ b/internal/service/s3/bucket.go @@ -381,10 +381,9 @@ func ResourceBucket() *schema.Resource { }, "acceleration_status": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice(s3.BucketAccelerateStatus_Values(), false), + Type: schema.TypeString, + Computed: true, + Deprecated: "Use the aws_s3_bucket_accelerate_configuration resource instead", }, "request_payer": { @@ -804,12 +803,6 @@ func resourceBucketUpdate(d *schema.ResourceData, meta interface{}) error { } } - if d.HasChange("acceleration_status") { - if err := resourceBucketAccelerationUpdate(conn, d); err != nil { - return err - } - } - if d.HasChange("replication_configuration") { if err := resourceBucketInternalReplicationConfigurationUpdate(conn, d); err != nil { return err @@ -1007,9 +1000,10 @@ func resourceBucketRead(d *schema.ResourceData, meta interface{}) error { }) // Amazon S3 Transfer Acceleration might not be supported in the region - if err != nil && !tfawserr.ErrMessageContains(err, "MethodNotAllowed", "") && !tfawserr.ErrMessageContains(err, "UnsupportedArgument", "") { - return fmt.Errorf("error getting S3 Bucket acceleration configuration: %s", err) + if err != nil && !tfawserr.ErrCodeEquals(err, ErrCodeMethodNotAllowed, ErrCodeUnsupportedArgument) { + return fmt.Errorf("error getting S3 Bucket acceleration configuration: %w", err) } + if accelerate, ok := accelerateResponse.(*s3.GetBucketAccelerateConfigurationOutput); ok { d.Set("acceleration_status", accelerate.Status) } @@ -1649,28 +1643,6 @@ func resourceBucketInternalLoggingUpdate(conn *s3.S3, d *schema.ResourceData) er return nil } -func resourceBucketAccelerationUpdate(conn *s3.S3, d *schema.ResourceData) error { - bucket := d.Get("bucket").(string) - enableAcceleration := d.Get("acceleration_status").(string) - - i := &s3.PutBucketAccelerateConfigurationInput{ - Bucket: aws.String(bucket), - AccelerateConfiguration: &s3.AccelerateConfiguration{ - Status: aws.String(enableAcceleration), - }, - } - log.Printf("[DEBUG] S3 put bucket acceleration: %#v", i) - - _, err := verify.RetryOnAWSCode(s3.ErrCodeNoSuchBucket, func() (interface{}, error) { - return conn.PutBucketAccelerateConfiguration(i) - }) - if err != nil { - return fmt.Errorf("Error putting S3 acceleration: %s", err) - } - - return nil -} - func resourceBucketInternalServerSideEncryptionConfigurationUpdate(conn *s3.S3, d *schema.ResourceData) error { bucket := d.Get("bucket").(string) serverSideEncryptionConfiguration := d.Get("server_side_encryption_configuration").([]interface{}) diff --git a/internal/service/s3/bucket_accelerate_configuration_test.go b/internal/service/s3/bucket_accelerate_configuration_test.go index 389d9d3e7a1..aacc2f8c345 100644 --- a/internal/service/s3/bucket_accelerate_configuration_test.go +++ b/internal/service/s3/bucket_accelerate_configuration_test.go @@ -192,12 +192,6 @@ func testAccBucketAccelerateConfigurationBasicConfig(bucketName, status string) return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q - - lifecycle { - ignore_changes = [ - acceleration_status - ] - } } resource "aws_s3_bucket_accelerate_configuration" "test" { diff --git a/internal/service/s3/bucket_test.go b/internal/service/s3/bucket_test.go index 3ac26fd72b0..9c35963629f 100644 --- a/internal/service/s3/bucket_test.go +++ b/internal/service/s3/bucket_test.go @@ -16,7 +16,6 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/service/cloudformation" - "github.com/aws/aws-sdk-go/service/cloudfront" "github.com/aws/aws-sdk-go/service/s3" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -372,43 +371,6 @@ func TestAccS3Bucket_Basic_generatedName(t *testing.T) { }) } -func TestAccS3Bucket_Basic_acceleration(t *testing.T) { - bucketName := sdkacctest.RandomWithPrefix("tf-test-bucket") - resourceName := "aws_s3_bucket.bucket" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - acctest.PreCheck(t) - acctest.PreCheckPartitionHasService(cloudfront.EndpointsID, t) - }, - ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketDestroy, - Steps: []resource.TestStep{ - { - Config: testAccBucketWithAccelerationConfig(bucketName), - Check: resource.ComposeTestCheckFunc( - testAccCheckBucketExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "acceleration_status", "Enabled"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force_destroy", "acl"}, - }, - { - Config: testAccBucketWithoutAccelerationConfig(bucketName), - Check: resource.ComposeTestCheckFunc( - testAccCheckBucketExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "acceleration_status", "Suspended"), - ), - }, - }, - }) -} - func TestAccS3Bucket_Security_policy(t *testing.T) { bucketName := sdkacctest.RandomWithPrefix("tf-test-bucket") partition := acctest.Partition() @@ -3043,24 +3005,6 @@ resource "aws_s3_bucket_acl" "test6" { `, randInt) } -func testAccBucketWithAccelerationConfig(bucketName string) string { - return fmt.Sprintf(` -resource "aws_s3_bucket" "bucket" { - bucket = %[1]q - acceleration_status = "Enabled" -} -`, bucketName) -} - -func testAccBucketWithoutAccelerationConfig(bucketName string) string { - return fmt.Sprintf(` -resource "aws_s3_bucket" "bucket" { - bucket = %[1]q - acceleration_status = "Suspended" -} -`, bucketName) -} - func testAccBucketWithPolicyConfig(bucketName, partition string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "bucket" { diff --git a/internal/service/s3/errors.go b/internal/service/s3/errors.go index ca656827361..4e43d24db69 100644 --- a/internal/service/s3/errors.go +++ b/internal/service/s3/errors.go @@ -4,6 +4,7 @@ package s3 // https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#pkg-constants const ( + ErrCodeMethodNotAllowed = "MethodNotAllowed" ErrCodeNoSuchConfiguration = "NoSuchConfiguration" ErrCodeNoSuchCORSConfiguration = "NoSuchCORSConfiguration" ErrCodeNoSuchLifecycleConfiguration = "NoSuchLifecycleConfiguration" @@ -13,4 +14,5 @@ const ( ErrCodeObjectLockConfigurationNotFound = "ObjectLockConfigurationNotFoundError" ErrCodeOperationAborted = "OperationAborted" ErrCodeServerSideEncryptionConfigurationNotFound = "ServerSideEncryptionConfigurationNotFoundError" + ErrCodeUnsupportedArgument = "UnsupportedArgument" ) diff --git a/website/docs/guides/version-4-upgrade.html.md b/website/docs/guides/version-4-upgrade.html.md index 4396069ae11..f35029a50ef 100644 --- a/website/docs/guides/version-4-upgrade.html.md +++ b/website/docs/guides/version-4-upgrade.html.md @@ -689,6 +689,60 @@ To help distribute the management of S3 bucket settings via independent resource have become read-only. Configurations dependent on these arguments should be updated to use the corresponding `aws_s3_bucket_*` resource. Once updated, new `aws_s3_bucket_*` resources should be imported into Terraform state. +### `acceleration_status` Argument deprecation + +Switch your Terraform configuration to the `aws_s3_bucket_accelerate_configuration` resource instead. + +For example, given this previous configuration: + +```terraform +resource "aws_s3_bucket" "example" { + # ... other configuration ... + acceleration_status = "Enabled" +} +``` + +It will receive the following error after upgrading: + +``` +│ Error: Value for unconfigurable attribute +│ +│ with aws_s3_bucket.example, +│ on main.tf line 1, in resource "aws_s3_bucket" "example": +│ 1: resource "aws_s3_bucket" "example" { +│ +│ Can't configure a value for "acceleration_status": its value will be decided automatically based on the result of applying this configuration. +``` + +Since the `acceleration_status` argument changed to read-only, the recommendation is to update the configuration to use the `aws_s3_bucket_accelerate_configuration` +resource and remove any reference to `acceleration_status` in the `aws_s3_bucket` resource: + +```terraform +resource "aws_s3_bucket" "example" { + # ... other configuration ... +} + +resource "aws_s3_bucket_accelerate_configuration" "example" { + bucket = aws_s3_bucket.example.id + status = "Enabled" +} +``` + +It is then recommended running `terraform import` on each new resource to prevent data loss, e.g. + +```shell +$ terraform import aws_s3_bucket_accelerate_configuration.example example +aws_s3_bucket_accelerate_configuration.example: Importing from ID "example"... +aws_s3_bucket_accelerate_configuration.example: Import prepared! + Prepared aws_s3_bucket_accelerate_configuration for import +aws_s3_bucket_accelerate_configuration.example: Refreshing state... [id=example] + +Import successful! + +The resources that were imported are shown above. These resources are now in +your Terraform state and will henceforth be managed by Terraform. +``` + ### `cors_rule` Argument deprecation Switch your Terraform configuration to the `aws_s3_bucket_cors_configuration` resource instead. diff --git a/website/docs/r/s3_bucket.html.markdown b/website/docs/r/s3_bucket.html.markdown index cb4934e625e..c8083f56d9d 100644 --- a/website/docs/r/s3_bucket.html.markdown +++ b/website/docs/r/s3_bucket.html.markdown @@ -358,16 +358,10 @@ The following arguments are supported: * `versioning` - (Optional) A state of [versioning](https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html) (documented below) * `logging` - (Optional) A settings of [bucket logging](https://docs.aws.amazon.com/AmazonS3/latest/UG/ManagingBucketLogging.html) (documented below). * `lifecycle_rule` - (Optional) A configuration of [object lifecycle management](http://docs.aws.amazon.com/AmazonS3/latest/dev/object-lifecycle-mgmt.html) (documented below). -* `acceleration_status` - (Optional) Sets the accelerate configuration of an existing bucket. Can be `Enabled` or `Suspended`. -Can be either `BucketOwner` or `Requester`. By default, the owner of the S3 bucket would incur -the costs of any data transfer. See [Requester Pays Buckets](http://docs.aws.amazon.com/AmazonS3/latest/dev/RequesterPaysBuckets.html) -developer guide for more information. * `replication_configuration` - (Optional) A configuration of [replication configuration](http://docs.aws.amazon.com/AmazonS3/latest/dev/crr.html) (documented below). * `server_side_encryption_configuration` - (Optional) A configuration of [server-side encryption configuration](http://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html) (documented below) * `object_lock_configuration` - (Optional) A configuration of [S3 object locking](https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html) (documented below) -~> **NOTE:** You cannot use `acceleration_status` in `cn-north-1` or `us-gov-west-1` - The `versioning` object supports the following: * `enabled` - (Optional) Enable versioning. Once you version-enable a bucket, it can never return to an unversioned state. You can, however, suspend versioning on that bucket. @@ -532,6 +526,7 @@ Once you create a bucket with S3 Object Lock enabled, you can't disable Object L In addition to all arguments above, the following attributes are exported: * `id` - The name of the bucket. +* `acceleration_status` - (Optional) The accelerate configuration status of the bucket. Not available in `cn-north-1` or `us-gov-west-1`. * `arn` - The ARN of the bucket. Will be of format `arn:aws:s3:::bucketname`. * `bucket_domain_name` - The bucket domain name. Will be of format `bucketname.s3.amazonaws.com`. * `bucket_regional_domain_name` - The bucket region-specific domain name. The bucket domain name including the region name, please refer [here](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) for format. Note: The AWS CloudFront allows specifying S3 region-specific endpoint when creating S3 origin, it will prevent [redirect issues](https://forums.aws.amazon.com/thread.jspa?threadID=216814) from CloudFront to S3 Origin URL.