diff --git a/.changelog/22045.txt b/.changelog/22045.txt new file mode 100644 index 00000000000..5357a18e89b --- /dev/null +++ b/.changelog/22045.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_s3_bucket_notification: Add `eventbridge` argument +``` diff --git a/internal/service/s3/bucket_notification.go b/internal/service/s3/bucket_notification.go index d6528050a97..e011472e9f6 100644 --- a/internal/service/s3/bucket_notification.go +++ b/internal/service/s3/bucket_notification.go @@ -32,6 +32,12 @@ func ResourceBucketNotification() *schema.Resource { ForceNew: true, }, + "eventbridge": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "topic": { Type: schema.TypeList, Optional: true, @@ -135,6 +141,13 @@ func resourceBucketNotificationPut(d *schema.ResourceData, meta interface{}) err conn := meta.(*conns.AWSClient).S3Conn bucket := d.Get("bucket").(string) + // EventBridge + eventbridgeNotifications := d.Get("eventbridge").(bool) + var eventbridgeConfig *s3.EventBridgeConfiguration + if eventbridgeNotifications { + eventbridgeConfig = &s3.EventBridgeConfiguration{} + } + // TopicNotifications topicNotifications := d.Get("topic").([]interface{}) topicConfigs := make([]*s3.TopicConfiguration, 0, len(topicNotifications)) @@ -295,6 +308,9 @@ func resourceBucketNotificationPut(d *schema.ResourceData, meta interface{}) err } notificationConfiguration := &s3.NotificationConfiguration{} + if eventbridgeConfig != nil { + notificationConfiguration.EventBridgeConfiguration = eventbridgeConfig + } if len(lambdaConfigs) > 0 { notificationConfiguration.LambdaFunctionConfigurations = lambdaConfigs } @@ -380,6 +396,9 @@ func resourceBucketNotificationRead(d *schema.ResourceData, meta interface{}) er d.Set("bucket", d.Id()) + // EventBridge Notification + d.Set("eventbridge", notificationConfigs.EventBridgeConfiguration != nil) + // Topic Notification if err := d.Set("topic", flattenTopicConfigurations(notificationConfigs.TopicConfigurations)); err != nil { return fmt.Errorf("error reading S3 bucket \"%s\" topic notification: %s", d.Id(), err) diff --git a/internal/service/s3/bucket_notification_test.go b/internal/service/s3/bucket_notification_test.go index 6eb2daaa43e..fd4515e2e14 100644 --- a/internal/service/s3/bucket_notification_test.go +++ b/internal/service/s3/bucket_notification_test.go @@ -17,6 +17,30 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" ) +func TestAccS3BucketNotification_eventbridge(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_notification.notification" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckBucketNotificationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketNotificationEventBridgeConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketEventBridgeNotification("aws_s3_bucket.bucket")), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccS3BucketNotification_lambdaFunction(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_s3_bucket_notification.notification" @@ -361,6 +385,31 @@ func testAccCheckBucketTopicNotification(n, i, t string, events []string, filter } } +func testAccCheckBucketEventBridgeNotification(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs := s.RootModule().Resources[n] + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn + + err := resource.Retry(1*time.Minute, func() *resource.RetryError { + out, err := conn.GetBucketNotificationConfiguration(&s3.GetBucketNotificationConfigurationRequest{ + Bucket: aws.String(rs.Primary.ID), + }) + + if err != nil { + return resource.NonRetryableError(fmt.Errorf("GetBucketNotification error: %v", err)) + } + + if out.EventBridgeConfiguration == nil { + return resource.RetryableError(fmt.Errorf("No EventBridge configuration: %#v", out)) + } else { + return nil + } + }) + + return err + } +} + func testAccCheckBucketQueueNotification(n, i, t string, events []string, filters *s3.KeyFilter) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] @@ -475,6 +524,23 @@ func testAccCheckBucketLambdaFunctionConfiguration(n, i, t string, events []stri } } +func testAccBucketNotificationEventBridgeConfig(rName string) string { + return fmt.Sprintf(` +data "aws_partition" "current" {} + +resource "aws_s3_bucket" "bucket" { + bucket = %[1]q + acl = "public-read" +} + +resource "aws_s3_bucket_notification" "notification" { + bucket = aws_s3_bucket.bucket.id + + eventbridge = true +} +`, rName) +} + func testAccBucketNotificationTopicMultipleConfig(rName string) string { return fmt.Sprintf(` data "aws_partition" "current" {} diff --git a/internal/service/s3/bucket_replication_configuration_test.go b/internal/service/s3/bucket_replication_configuration_test.go index 221a791fe33..8dd0e32c072 100644 --- a/internal/service/s3/bucket_replication_configuration_test.go +++ b/internal/service/s3/bucket_replication_configuration_test.go @@ -130,7 +130,7 @@ func TestAccS3BucketReplicationConfiguration_multipleDestinationsEmptyFilter(t * acctest.PreCheck(t) acctest.PreCheckMultipleRegion(t, 2) }, - ErrorCheck: testAccErrorCheckSkipS3(t), + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), ProviderFactories: acctest.FactoriesAlternate(&providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ @@ -189,7 +189,7 @@ func TestAccS3BucketReplicationConfiguration_multipleDestinationsNonEmptyFilter( acctest.PreCheck(t) acctest.PreCheckMultipleRegion(t, 2) }, - ErrorCheck: testAccErrorCheckSkipS3(t), + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), ProviderFactories: acctest.FactoriesAlternate(&providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ @@ -240,7 +240,7 @@ func TestAccS3BucketReplicationConfiguration_twoDestination(t *testing.T) { acctest.PreCheck(t) acctest.PreCheckMultipleRegion(t, 2) }, - ErrorCheck: testAccErrorCheckSkipS3(t), + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), ProviderFactories: acctest.FactoriesAlternate(&providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ diff --git a/internal/service/s3/bucket_test.go b/internal/service/s3/bucket_test.go index 227c16afbd3..491029b2bd0 100644 --- a/internal/service/s3/bucket_test.go +++ b/internal/service/s3/bucket_test.go @@ -31,6 +31,18 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) +func init() { + acctest.RegisterServiceErrorCheckFunc(s3.EndpointsID, testAccErrorCheckSkip) +} + +// testAccErrorCheckSkip skips tests that have error messages indicating unsupported features +func testAccErrorCheckSkip(t *testing.T) resource.ErrorCheckFunc { + return acctest.ErrorCheckSkipMessagesContaining(t, + "Number of distinct destination bucket ARNs cannot exceed", + "destination is not allowed", + ) +} + func TestAccS3Bucket_Basic_basic(t *testing.T) { bucketName := sdkacctest.RandomWithPrefix("tf-test-bucket") region := acctest.Region() @@ -1586,7 +1598,7 @@ func TestAccS3Bucket_Replication_multipleDestinationsEmptyFilter(t *testing.T) { acctest.PreCheck(t) acctest.PreCheckMultipleRegion(t, 2) }, - ErrorCheck: testAccErrorCheckSkipS3(t), + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), ProviderFactories: acctest.FactoriesAlternate(&providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ @@ -1653,7 +1665,7 @@ func TestAccS3Bucket_Replication_multipleDestinationsNonEmptyFilter(t *testing.T acctest.PreCheck(t) acctest.PreCheckMultipleRegion(t, 2) }, - ErrorCheck: testAccErrorCheckSkipS3(t), + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), ProviderFactories: acctest.FactoriesAlternate(&providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ @@ -1724,7 +1736,7 @@ func TestAccS3Bucket_Replication_twoDestination(t *testing.T) { acctest.PreCheck(t) acctest.PreCheckMultipleRegion(t, 2) }, - ErrorCheck: testAccErrorCheckSkipS3(t), + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), ProviderFactories: acctest.FactoriesAlternate(&providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ @@ -2890,13 +2902,6 @@ func TestWebsiteEndpoint(t *testing.T) { } } -// testAccErrorCheckSkipS3 skips tests that have error messages indicating unsupported features -func testAccErrorCheckSkipS3(t *testing.T) resource.ErrorCheckFunc { - return acctest.ErrorCheckSkipMessagesContaining(t, - "Number of distinct destination bucket ARNs cannot exceed", - ) -} - func testAccCheckBucketDestroy(s *terraform.State) error { return testAccCheckBucketDestroyWithProvider(s, acctest.Provider) } diff --git a/website/docs/r/s3_bucket_notification.html.markdown b/website/docs/r/s3_bucket_notification.html.markdown index eec6e65bffe..96c292514b0 100644 --- a/website/docs/r/s3_bucket_notification.html.markdown +++ b/website/docs/r/s3_bucket_notification.html.markdown @@ -298,36 +298,40 @@ For Terraform's [JSON syntax](https://www.terraform.io/docs/configuration/syntax ## Argument Reference -The following arguments are supported: +The following arguments are required: -* `bucket` - (Required) The name of the bucket to put notification configuration. -* `topic` - (Optional) The notification configuration to SNS Topic (documented below). -* `queue` - (Optional) The notification configuration to SQS Queue (documented below). -* `lambda_function` - (Optional, Multiple) Used to configure notifications to a Lambda Function (documented below). +* `bucket` - (Required) Name of the bucket for notification configuration. -The `topic` notification configuration supports the following: +The following arguments are optional: -* `id` - (Optional) Specifies unique identifier for each of the notification configurations. -* `topic_arn` - (Required) Specifies Amazon SNS topic ARN. -* `events` - (Required) Specifies [event](http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-event-types-and-destinations) for which to send notifications. -* `filter_prefix` - (Optional) Specifies object key name prefix. -* `filter_suffix` - (Optional) Specifies object key name suffix. +* `eventbridge` - (Optional) Whether to enable Amazon EventBridge notifications. +* `lambda_function` - (Optional, Multiple) Used to configure notifications to a Lambda Function. See below. +* `queue` - (Optional) Notification configuration to SQS Queue. See below. +* `topic` - (Optional) Notification configuration to SNS Topic. See below. -The `queue` notification configuration supports the following: +### `lambda_function` -* `id` - (Optional) Specifies unique identifier for each of the notification configurations. -* `queue_arn` - (Required) Specifies Amazon SQS queue ARN. -* `events` - (Required) Specifies [event](http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-event-types-and-destinations) for which to send notifications. -* `filter_prefix` - (Optional) Specifies object key name prefix. -* `filter_suffix` - (Optional) Specifies object key name suffix. +* `events` - (Required) [Event](http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-event-types-and-destinations) for which to send notifications. +* `filter_prefix` - (Optional) Object key name prefix. +* `filter_suffix` - (Optional) Object key name suffix. +* `id` - (Optional) Unique identifier for each of the notification configurations. +* `lambda_function_arn` - (Required) Lambda function ARN. -The `lambda_function` notification configuration supports the following: +### `queue` -* `id` - (Optional) Specifies unique identifier for each of the notification configurations. -* `lambda_function_arn` - (Required) Specifies Amazon Lambda function ARN. * `events` - (Required) Specifies [event](http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-event-types-and-destinations) for which to send notifications. -* `filter_prefix` - (Optional) Specifies object key name prefix. -* `filter_suffix` - (Optional) Specifies object key name suffix. +* `filter_prefix` - (Optional) Object key name prefix. +* `filter_suffix` - (Optional) Object key name suffix. +* `id` - (Optional) Unique identifier for each of the notification configurations. +* `queue_arn` - (Required) SQS queue ARN. + +### `topic` + +* `events` - (Required) [Event](http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-event-types-and-destinations) for which to send notifications. +* `filter_prefix` - (Optional) Object key name prefix. +* `filter_suffix` - (Optional) Object key name suffix. +* `id` - (Optional) Unique identifier for each of the notification configurations. +* `topic_arn` - (Required) SNS topic ARN. ## Attributes Reference