provider/aws: Support S3 bucket notification
* Implement aws_s3_bucket_notification resource
This commit is contained in:
parent
b04b508b54
commit
d646682d7a
|
@ -228,6 +228,7 @@ func Provider() terraform.ResourceProvider {
|
|||
"aws_route_table_association": resourceAwsRouteTableAssociation(),
|
||||
"aws_s3_bucket": resourceAwsS3Bucket(),
|
||||
"aws_s3_bucket_object": resourceAwsS3BucketObject(),
|
||||
"aws_s3_bucket_notification": resourceAwsS3BucketNotification(),
|
||||
"aws_security_group": resourceAwsSecurityGroup(),
|
||||
"aws_security_group_rule": resourceAwsSecurityGroupRule(),
|
||||
"aws_spot_instance_request": resourceAwsSpotInstanceRequest(),
|
||||
|
|
|
@ -0,0 +1,464 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
func resourceAwsS3BucketNotification() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsS3BucketNotificationPut,
|
||||
Read: resourceAwsS3BucketNotificationRead,
|
||||
Update: resourceAwsS3BucketNotificationPut,
|
||||
Delete: resourceAwsS3BucketNotificationDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"bucket": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"topic": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"filter_prefix": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"filter_suffix": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"topic_arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"events": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"queue": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"filter_prefix": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"filter_suffix": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"queue_arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"events": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"lambda_function": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"filter_prefix": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"filter_suffix": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"lambda_function_arn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"events": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsS3BucketNotificationPut(d *schema.ResourceData, meta interface{}) error {
|
||||
s3conn := meta.(*AWSClient).s3conn
|
||||
bucket := d.Get("bucket").(string)
|
||||
|
||||
// TopicNotifications
|
||||
topicNotifications := d.Get("topic").([]interface{})
|
||||
topicConfigs := make([]*s3.TopicConfiguration, 0, len(topicNotifications))
|
||||
for i, c := range topicNotifications {
|
||||
tc := &s3.TopicConfiguration{}
|
||||
|
||||
c := c.(map[string]interface{})
|
||||
|
||||
// Id
|
||||
if val, ok := c["id"].(string); ok && val != "" {
|
||||
tc.Id = aws.String(val)
|
||||
} else {
|
||||
tc.Id = aws.String(resource.PrefixedUniqueId("tf-s3-topic-"))
|
||||
}
|
||||
|
||||
// TopicArn
|
||||
if val, ok := c["topic_arn"].(string); ok {
|
||||
tc.TopicArn = aws.String(val)
|
||||
}
|
||||
|
||||
// Events
|
||||
events := d.Get(fmt.Sprintf("topic.%d.events", i)).(*schema.Set).List()
|
||||
tc.Events = make([]*string, 0, len(events))
|
||||
for _, e := range events {
|
||||
tc.Events = append(tc.Events, aws.String(e.(string)))
|
||||
}
|
||||
|
||||
// Filter
|
||||
filterRules := make([]*s3.FilterRule, 0, 2)
|
||||
if val, ok := c["filter_prefix"].(string); ok && val != "" {
|
||||
filterRule := &s3.FilterRule{
|
||||
Name: aws.String("prefix"),
|
||||
Value: aws.String(val),
|
||||
}
|
||||
filterRules = append(filterRules, filterRule)
|
||||
}
|
||||
if val, ok := c["filter_suffix"].(string); ok && val != "" {
|
||||
filterRule := &s3.FilterRule{
|
||||
Name: aws.String("suffix"),
|
||||
Value: aws.String(val),
|
||||
}
|
||||
filterRules = append(filterRules, filterRule)
|
||||
}
|
||||
if len(filterRules) > 0 {
|
||||
tc.Filter = &s3.NotificationConfigurationFilter{
|
||||
Key: &s3.KeyFilter{
|
||||
FilterRules: filterRules,
|
||||
},
|
||||
}
|
||||
}
|
||||
topicConfigs = append(topicConfigs, tc)
|
||||
}
|
||||
|
||||
// SQS
|
||||
queueNotifications := d.Get("queue").([]interface{})
|
||||
queueConfigs := make([]*s3.QueueConfiguration, 0, len(queueNotifications))
|
||||
for i, c := range queueNotifications {
|
||||
qc := &s3.QueueConfiguration{}
|
||||
|
||||
c := c.(map[string]interface{})
|
||||
|
||||
// Id
|
||||
if val, ok := c["id"].(string); ok && val != "" {
|
||||
qc.Id = aws.String(val)
|
||||
} else {
|
||||
qc.Id = aws.String(resource.PrefixedUniqueId("tf-s3-queue-"))
|
||||
}
|
||||
|
||||
// QueueArn
|
||||
if val, ok := c["queue_arn"].(string); ok {
|
||||
qc.QueueArn = aws.String(val)
|
||||
}
|
||||
|
||||
// Events
|
||||
events := d.Get(fmt.Sprintf("queue.%d.events", i)).(*schema.Set).List()
|
||||
qc.Events = make([]*string, 0, len(events))
|
||||
for _, e := range events {
|
||||
qc.Events = append(qc.Events, aws.String(e.(string)))
|
||||
}
|
||||
|
||||
// Filter
|
||||
filterRules := make([]*s3.FilterRule, 0, 2)
|
||||
if val, ok := c["filter_prefix"].(string); ok && val != "" {
|
||||
filterRule := &s3.FilterRule{
|
||||
Name: aws.String("prefix"),
|
||||
Value: aws.String(val),
|
||||
}
|
||||
filterRules = append(filterRules, filterRule)
|
||||
}
|
||||
if val, ok := c["filter_suffix"].(string); ok && val != "" {
|
||||
filterRule := &s3.FilterRule{
|
||||
Name: aws.String("suffix"),
|
||||
Value: aws.String(val),
|
||||
}
|
||||
filterRules = append(filterRules, filterRule)
|
||||
}
|
||||
if len(filterRules) > 0 {
|
||||
qc.Filter = &s3.NotificationConfigurationFilter{
|
||||
Key: &s3.KeyFilter{
|
||||
FilterRules: filterRules,
|
||||
},
|
||||
}
|
||||
}
|
||||
queueConfigs = append(queueConfigs, qc)
|
||||
}
|
||||
|
||||
// Lambda
|
||||
lambdaFunctionNotifications := d.Get("lambda_function").([]interface{})
|
||||
lambdaConfigs := make([]*s3.LambdaFunctionConfiguration, 0, len(lambdaFunctionNotifications))
|
||||
for i, c := range lambdaFunctionNotifications {
|
||||
lc := &s3.LambdaFunctionConfiguration{}
|
||||
|
||||
c := c.(map[string]interface{})
|
||||
|
||||
// Id
|
||||
if val, ok := c["id"].(string); ok && val != "" {
|
||||
lc.Id = aws.String(val)
|
||||
} else {
|
||||
lc.Id = aws.String(resource.PrefixedUniqueId("tf-s3-lambda-"))
|
||||
}
|
||||
|
||||
// LambdaFunctionArn
|
||||
if val, ok := c["lambda_function_arn"].(string); ok {
|
||||
lc.LambdaFunctionArn = aws.String(val)
|
||||
}
|
||||
|
||||
// Events
|
||||
events := d.Get(fmt.Sprintf("lambda_function.%d.events", i)).(*schema.Set).List()
|
||||
lc.Events = make([]*string, 0, len(events))
|
||||
for _, e := range events {
|
||||
lc.Events = append(lc.Events, aws.String(e.(string)))
|
||||
}
|
||||
|
||||
// Filter
|
||||
filterRules := make([]*s3.FilterRule, 0, 2)
|
||||
if val, ok := c["filter_prefix"].(string); ok && val != "" {
|
||||
filterRule := &s3.FilterRule{
|
||||
Name: aws.String("prefix"),
|
||||
Value: aws.String(val),
|
||||
}
|
||||
filterRules = append(filterRules, filterRule)
|
||||
}
|
||||
if val, ok := c["filter_suffix"].(string); ok && val != "" {
|
||||
filterRule := &s3.FilterRule{
|
||||
Name: aws.String("suffix"),
|
||||
Value: aws.String(val),
|
||||
}
|
||||
filterRules = append(filterRules, filterRule)
|
||||
}
|
||||
if len(filterRules) > 0 {
|
||||
lc.Filter = &s3.NotificationConfigurationFilter{
|
||||
Key: &s3.KeyFilter{
|
||||
FilterRules: filterRules,
|
||||
},
|
||||
}
|
||||
}
|
||||
lambdaConfigs = append(lambdaConfigs, lc)
|
||||
}
|
||||
|
||||
notificationConfiguration := &s3.NotificationConfiguration{}
|
||||
if len(lambdaConfigs) > 0 {
|
||||
notificationConfiguration.LambdaFunctionConfigurations = lambdaConfigs
|
||||
}
|
||||
if len(queueConfigs) > 0 {
|
||||
notificationConfiguration.QueueConfigurations = queueConfigs
|
||||
}
|
||||
if len(topicConfigs) > 0 {
|
||||
notificationConfiguration.TopicConfigurations = topicConfigs
|
||||
}
|
||||
i := &s3.PutBucketNotificationConfigurationInput{
|
||||
Bucket: aws.String(bucket),
|
||||
NotificationConfiguration: notificationConfiguration,
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] S3 bucket: %s, Putting notification: %v", bucket, i)
|
||||
err := resource.Retry(1*time.Minute, func() *resource.RetryError {
|
||||
if _, err := s3conn.PutBucketNotificationConfiguration(i); err != nil {
|
||||
if awserr, ok := err.(awserr.Error); ok {
|
||||
switch awserr.Message() {
|
||||
case "Unable to validate the following destination configurations":
|
||||
return resource.RetryableError(awserr)
|
||||
}
|
||||
}
|
||||
// Didn't recognize the error, so shouldn't retry.
|
||||
return resource.NonRetryableError(err)
|
||||
}
|
||||
// Successful put configuration
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error putting S3 notification configuration: %s", err)
|
||||
}
|
||||
|
||||
d.SetId(bucket)
|
||||
|
||||
return resourceAwsS3BucketNotificationRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsS3BucketNotificationDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
s3conn := meta.(*AWSClient).s3conn
|
||||
|
||||
i := &s3.PutBucketNotificationConfigurationInput{
|
||||
Bucket: aws.String(d.Id()),
|
||||
NotificationConfiguration: &s3.NotificationConfiguration{},
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] S3 bucket: %s, Deleting notification: %v", d.Id(), i)
|
||||
_, err := s3conn.PutBucketNotificationConfiguration(i)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting S3 notification configuration: %s", err)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsS3BucketNotificationRead(d *schema.ResourceData, meta interface{}) error {
|
||||
s3conn := meta.(*AWSClient).s3conn
|
||||
|
||||
var err error
|
||||
_, err = s3conn.HeadBucket(&s3.HeadBucketInput{
|
||||
Bucket: aws.String(d.Id()),
|
||||
})
|
||||
if err != nil {
|
||||
if awsError, ok := err.(awserr.RequestFailure); ok && awsError.StatusCode() == 404 {
|
||||
log.Printf("[WARN] S3 Bucket (%s) not found, error code (404)", d.Id())
|
||||
d.SetId("")
|
||||
return nil
|
||||
} else {
|
||||
// some of the AWS SDK's errors can be empty strings, so let's add
|
||||
// some additional context.
|
||||
return fmt.Errorf("error reading S3 bucket \"%s\": %s", d.Id(), err)
|
||||
}
|
||||
}
|
||||
|
||||
// Read the notification configuration
|
||||
notificationConfigs, err := s3conn.GetBucketNotificationConfiguration(&s3.GetBucketNotificationConfigurationRequest{
|
||||
Bucket: aws.String(d.Id()),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] S3 Bucket: %s, get notification: %v", d.Id(), notificationConfigs)
|
||||
// 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)
|
||||
}
|
||||
|
||||
// SQS Notification
|
||||
if err := d.Set("queue", flattenQueueConfigurations(notificationConfigs.QueueConfigurations)); err != nil {
|
||||
return fmt.Errorf("error reading S3 bucket \"%s\" queue notification: %s", d.Id(), err)
|
||||
}
|
||||
|
||||
// Lambda Notification
|
||||
if err := d.Set("lambda_function", flattenLambdaFunctionConfigurations(notificationConfigs.LambdaFunctionConfigurations)); err != nil {
|
||||
return fmt.Errorf("error reading S3 bucket \"%s\" lambda function notification: %s", d.Id(), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func flattenNotificationConfigurationFilter(filter *s3.NotificationConfigurationFilter) map[string]interface{} {
|
||||
filterRules := map[string]interface{}{}
|
||||
for _, f := range filter.Key.FilterRules {
|
||||
if strings.ToLower(*f.Name) == s3.FilterRuleNamePrefix {
|
||||
filterRules["filter_prefix"] = *f.Value
|
||||
}
|
||||
if strings.ToLower(*f.Name) == s3.FilterRuleNameSuffix {
|
||||
filterRules["filter_suffix"] = *f.Value
|
||||
}
|
||||
}
|
||||
return filterRules
|
||||
}
|
||||
|
||||
func flattenTopicConfigurations(configs []*s3.TopicConfiguration) []map[string]interface{} {
|
||||
topicNotifications := make([]map[string]interface{}, 0, len(configs))
|
||||
for _, notification := range configs {
|
||||
var conf map[string]interface{}
|
||||
if filter := notification.Filter; filter != nil {
|
||||
conf = flattenNotificationConfigurationFilter(filter)
|
||||
} else {
|
||||
conf = map[string]interface{}{}
|
||||
}
|
||||
|
||||
conf["id"] = *notification.Id
|
||||
conf["events"] = schema.NewSet(schema.HashString, flattenStringList(notification.Events))
|
||||
conf["topic_arn"] = *notification.TopicArn
|
||||
topicNotifications = append(topicNotifications, conf)
|
||||
}
|
||||
|
||||
return topicNotifications
|
||||
}
|
||||
|
||||
func flattenQueueConfigurations(configs []*s3.QueueConfiguration) []map[string]interface{} {
|
||||
queueNotifications := make([]map[string]interface{}, 0, len(configs))
|
||||
for _, notification := range configs {
|
||||
var conf map[string]interface{}
|
||||
if filter := notification.Filter; filter != nil {
|
||||
conf = flattenNotificationConfigurationFilter(filter)
|
||||
} else {
|
||||
conf = map[string]interface{}{}
|
||||
}
|
||||
|
||||
conf["id"] = *notification.Id
|
||||
conf["events"] = schema.NewSet(schema.HashString, flattenStringList(notification.Events))
|
||||
conf["queue_arn"] = *notification.QueueArn
|
||||
queueNotifications = append(queueNotifications, conf)
|
||||
}
|
||||
|
||||
return queueNotifications
|
||||
}
|
||||
|
||||
func flattenLambdaFunctionConfigurations(configs []*s3.LambdaFunctionConfiguration) []map[string]interface{} {
|
||||
lambdaFunctionNotifications := make([]map[string]interface{}, 0, len(configs))
|
||||
for _, notification := range configs {
|
||||
var conf map[string]interface{}
|
||||
if filter := notification.Filter; filter != nil {
|
||||
conf = flattenNotificationConfigurationFilter(filter)
|
||||
} else {
|
||||
conf = map[string]interface{}{}
|
||||
}
|
||||
|
||||
conf["id"] = *notification.Id
|
||||
conf["events"] = schema.NewSet(schema.HashString, flattenStringList(notification.Events))
|
||||
conf["lambda_function_arn"] = *notification.LambdaFunctionArn
|
||||
lambdaFunctionNotifications = append(lambdaFunctionNotifications, conf)
|
||||
}
|
||||
|
||||
return lambdaFunctionNotifications
|
||||
}
|
|
@ -0,0 +1,519 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
func TestAccAWSS3Bucket_Notification(t *testing.T) {
|
||||
rInt := acctest.RandInt()
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSS3BucketNotificationDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSS3BucketConfigWithTopicNotification(rInt),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSS3BucketTopicNotification(
|
||||
"aws_s3_bucket.bucket",
|
||||
"notification-sns1",
|
||||
"aws_sns_topic.topic",
|
||||
[]string{"s3:ObjectCreated:*", "s3:ObjectRemoved:Delete"},
|
||||
&s3.KeyFilter{
|
||||
FilterRules: []*s3.FilterRule{
|
||||
&s3.FilterRule{
|
||||
Name: aws.String("Prefix"),
|
||||
Value: aws.String(fmt.Sprintf("%d/", rInt)),
|
||||
},
|
||||
&s3.FilterRule{
|
||||
Name: aws.String("Suffix"),
|
||||
Value: aws.String(".txt"),
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
testAccCheckAWSS3BucketTopicNotification(
|
||||
"aws_s3_bucket.bucket",
|
||||
"notification-sns2",
|
||||
"aws_sns_topic.topic",
|
||||
[]string{"s3:ObjectCreated:*", "s3:ObjectRemoved:Delete"},
|
||||
&s3.KeyFilter{
|
||||
FilterRules: []*s3.FilterRule{
|
||||
&s3.FilterRule{
|
||||
Name: aws.String("Suffix"),
|
||||
Value: aws.String(".log"),
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccAWSS3BucketConfigWithQueueNotification(rInt),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSS3BucketQueueNotification(
|
||||
"aws_s3_bucket.bucket",
|
||||
"notification-sqs",
|
||||
"aws_sqs_queue.queue",
|
||||
[]string{"s3:ObjectCreated:*", "s3:ObjectRemoved:Delete"},
|
||||
&s3.KeyFilter{
|
||||
FilterRules: []*s3.FilterRule{
|
||||
&s3.FilterRule{
|
||||
Name: aws.String("Prefix"),
|
||||
Value: aws.String(fmt.Sprintf("%d/", rInt)),
|
||||
},
|
||||
&s3.FilterRule{
|
||||
Name: aws.String("Suffix"),
|
||||
Value: aws.String(".mp4"),
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccAWSS3BucketConfigWithLambdaNotification(rInt),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSS3BucketLambdaFunctionConfiguration(
|
||||
"aws_s3_bucket.bucket",
|
||||
"notification-lambda",
|
||||
"aws_lambda_function.func",
|
||||
[]string{"s3:ObjectCreated:*", "s3:ObjectRemoved:Delete"},
|
||||
&s3.KeyFilter{
|
||||
FilterRules: []*s3.FilterRule{
|
||||
&s3.FilterRule{
|
||||
Name: aws.String("Prefix"),
|
||||
Value: aws.String(fmt.Sprintf("%d/", rInt)),
|
||||
},
|
||||
&s3.FilterRule{
|
||||
Name: aws.String("Suffix"),
|
||||
Value: aws.String(".png"),
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAWSS3Bucket_NotificationWithoutFilter(t *testing.T) {
|
||||
rInt := acctest.RandInt()
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSS3BucketNotificationDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSS3BucketConfigWithTopicNotificationWithoutFilter(rInt),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSS3BucketTopicNotification(
|
||||
"aws_s3_bucket.bucket",
|
||||
"notification-sns1",
|
||||
"aws_sns_topic.topic",
|
||||
[]string{"s3:ObjectCreated:*", "s3:ObjectRemoved:Delete"},
|
||||
nil,
|
||||
),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAWSS3BucketNotificationDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).s3conn
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_s3_bucket_notification" {
|
||||
continue
|
||||
}
|
||||
err := resource.Retry(1*time.Minute, func() *resource.RetryError {
|
||||
out, err := conn.GetBucketNotificationConfiguration(&s3.GetBucketNotificationConfigurationRequest{
|
||||
Bucket: aws.String(rs.Primary.ID),
|
||||
})
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoSuchBucket" {
|
||||
return nil
|
||||
}
|
||||
return resource.NonRetryableError(err)
|
||||
}
|
||||
if len(out.TopicConfigurations) > 0 {
|
||||
return resource.RetryableError(fmt.Errorf("TopicConfigurations is exists: %v", out))
|
||||
}
|
||||
if len(out.LambdaFunctionConfigurations) > 0 {
|
||||
return resource.RetryableError(fmt.Errorf("LambdaFunctionConfigurations is exists: %v", out))
|
||||
}
|
||||
if len(out.QueueConfigurations) > 0 {
|
||||
return resource.RetryableError(fmt.Errorf("QueueConfigurations is exists: %v", out))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccCheckAWSS3BucketTopicNotification(n, i, t string, events []string, filters *s3.KeyFilter) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, _ := s.RootModule().Resources[n]
|
||||
topicArn := s.RootModule().Resources[t].Primary.ID
|
||||
conn := testAccProvider.Meta().(*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))
|
||||
}
|
||||
|
||||
eventSlice := sort.StringSlice(events)
|
||||
eventSlice.Sort()
|
||||
|
||||
outputTopics := out.TopicConfigurations
|
||||
matched := false
|
||||
for _, outputTopic := range outputTopics {
|
||||
if *outputTopic.Id == i {
|
||||
matched = true
|
||||
|
||||
if *outputTopic.TopicArn != topicArn {
|
||||
return resource.RetryableError(fmt.Errorf("bad topic arn, expected: %s, got %#v", topicArn, *outputTopic.TopicArn))
|
||||
}
|
||||
|
||||
if filters != nil {
|
||||
if !reflect.DeepEqual(filters, outputTopic.Filter.Key) {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification filters, expected: %#v, got %#v", filters, outputTopic.Filter.Key))
|
||||
}
|
||||
} else {
|
||||
if outputTopic.Filter != nil {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification filters, expected: nil, got %#v", outputTopic.Filter))
|
||||
}
|
||||
}
|
||||
|
||||
outputEventSlice := sort.StringSlice(aws.StringValueSlice(outputTopic.Events))
|
||||
outputEventSlice.Sort()
|
||||
if !reflect.DeepEqual(eventSlice, outputEventSlice) {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification events, expected: %#v, got %#v", events, outputEventSlice))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !matched {
|
||||
return resource.RetryableError(fmt.Errorf("No match topic configurations: %#v", out))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckAWSS3BucketQueueNotification(n, i, t string, events []string, filters *s3.KeyFilter) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, _ := s.RootModule().Resources[n]
|
||||
queueArn := s.RootModule().Resources[t].Primary.Attributes["arn"]
|
||||
conn := testAccProvider.Meta().(*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))
|
||||
}
|
||||
|
||||
eventSlice := sort.StringSlice(events)
|
||||
eventSlice.Sort()
|
||||
|
||||
outputQueues := out.QueueConfigurations
|
||||
matched := false
|
||||
for _, outputQueue := range outputQueues {
|
||||
if *outputQueue.Id == i {
|
||||
matched = true
|
||||
|
||||
if *outputQueue.QueueArn != queueArn {
|
||||
return resource.RetryableError(fmt.Errorf("bad queue arn, expected: %s, got %#v", queueArn, *outputQueue.QueueArn))
|
||||
}
|
||||
|
||||
if filters != nil {
|
||||
if !reflect.DeepEqual(filters, outputQueue.Filter.Key) {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification filters, expected: %#v, got %#v", filters, outputQueue.Filter.Key))
|
||||
}
|
||||
} else {
|
||||
if outputQueue.Filter != nil {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification filters, expected: nil, got %#v", outputQueue.Filter))
|
||||
}
|
||||
}
|
||||
|
||||
outputEventSlice := sort.StringSlice(aws.StringValueSlice(outputQueue.Events))
|
||||
outputEventSlice.Sort()
|
||||
if !reflect.DeepEqual(eventSlice, outputEventSlice) {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification events, expected: %#v, got %#v", events, outputEventSlice))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !matched {
|
||||
return resource.RetryableError(fmt.Errorf("No match queue configurations: %#v", out))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckAWSS3BucketLambdaFunctionConfiguration(n, i, t string, events []string, filters *s3.KeyFilter) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, _ := s.RootModule().Resources[n]
|
||||
funcArn := s.RootModule().Resources[t].Primary.Attributes["arn"]
|
||||
conn := testAccProvider.Meta().(*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))
|
||||
}
|
||||
|
||||
eventSlice := sort.StringSlice(events)
|
||||
eventSlice.Sort()
|
||||
|
||||
outputFunctions := out.LambdaFunctionConfigurations
|
||||
matched := false
|
||||
for _, outputFunc := range outputFunctions {
|
||||
if *outputFunc.Id == i {
|
||||
matched = true
|
||||
|
||||
if *outputFunc.LambdaFunctionArn != funcArn {
|
||||
return resource.RetryableError(fmt.Errorf("bad lambda function arn, expected: %s, got %#v", funcArn, *outputFunc.LambdaFunctionArn))
|
||||
}
|
||||
|
||||
if filters != nil {
|
||||
if !reflect.DeepEqual(filters, outputFunc.Filter.Key) {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification filters, expected: %#v, got %#v", filters, outputFunc.Filter.Key))
|
||||
}
|
||||
} else {
|
||||
if outputFunc.Filter != nil {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification filters, expected: nil, got %#v", outputFunc.Filter))
|
||||
}
|
||||
}
|
||||
|
||||
outputEventSlice := sort.StringSlice(aws.StringValueSlice(outputFunc.Events))
|
||||
outputEventSlice.Sort()
|
||||
if !reflect.DeepEqual(eventSlice, outputEventSlice) {
|
||||
return resource.RetryableError(fmt.Errorf("bad notification events, expected: %#v, got %#v", events, outputEventSlice))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !matched {
|
||||
return resource.RetryableError(fmt.Errorf("No match lambda function configurations: %#v", out))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func testAccAWSS3BucketConfigWithTopicNotification(randInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "aws_sns_topic" "topic" {
|
||||
name = "terraform-test-topic"
|
||||
policy = <<POLICY
|
||||
{
|
||||
"Version":"2012-10-17",
|
||||
"Statement":[{
|
||||
"Sid": "",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS":"*"},
|
||||
"Action": "SNS:Publish",
|
||||
"Resource": "arn:aws:sns:*:*:terraform-test-topic",
|
||||
"Condition":{
|
||||
"ArnLike":{"aws:SourceArn":"${aws_s3_bucket.bucket.arn}"}
|
||||
}
|
||||
}]
|
||||
}
|
||||
POLICY
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "bucket" {
|
||||
bucket = "tf-test-bucket-%d"
|
||||
acl = "public-read"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_notification" "notification" {
|
||||
bucket = "${aws_s3_bucket.bucket.id}"
|
||||
topic {
|
||||
id = "notification-sns1"
|
||||
topic_arn = "${aws_sns_topic.topic.arn}"
|
||||
events = [
|
||||
"s3:ObjectCreated:*",
|
||||
"s3:ObjectRemoved:Delete",
|
||||
]
|
||||
filter_prefix = "%d/"
|
||||
filter_suffix = ".txt"
|
||||
}
|
||||
topic {
|
||||
id = "notification-sns2"
|
||||
topic_arn = "${aws_sns_topic.topic.arn}"
|
||||
events = [
|
||||
"s3:ObjectCreated:*",
|
||||
"s3:ObjectRemoved:Delete",
|
||||
]
|
||||
filter_suffix = ".log"
|
||||
}
|
||||
}
|
||||
`, randInt, randInt)
|
||||
}
|
||||
|
||||
func testAccAWSS3BucketConfigWithQueueNotification(randInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "aws_sqs_queue" "queue" {
|
||||
name = "terraform-test-queue-%d"
|
||||
policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"sqs:SendMessage\",\"Resource\":\"arn:aws:sqs:*:*:terraform-test-queue-%d\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"${aws_s3_bucket.bucket.arn}\"}}}]}"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "bucket" {
|
||||
bucket = "tf-test-bucket-%d"
|
||||
acl = "public-read"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_notification" "notification" {
|
||||
bucket = "${aws_s3_bucket.bucket.id}"
|
||||
queue {
|
||||
id = "notification-sqs"
|
||||
queue_arn = "${aws_sqs_queue.queue.arn}"
|
||||
events = [
|
||||
"s3:ObjectCreated:*",
|
||||
"s3:ObjectRemoved:Delete",
|
||||
]
|
||||
filter_prefix = "%d/"
|
||||
filter_suffix = ".mp4"
|
||||
}
|
||||
}
|
||||
`, randInt, randInt, randInt, randInt)
|
||||
}
|
||||
|
||||
func testAccAWSS3BucketConfigWithLambdaNotification(randInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
|
||||
resource "aws_iam_role" "iam_for_lambda" {
|
||||
name = "iam_for_lambda"
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "lambda.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_lambda_permission" "allow_bucket" {
|
||||
statement_id = "AllowExecutionFromS3Bucket"
|
||||
action = "lambda:InvokeFunction"
|
||||
function_name = "${aws_lambda_function.func.arn}"
|
||||
principal = "s3.amazonaws.com"
|
||||
source_arn = "${aws_s3_bucket.bucket.arn}"
|
||||
}
|
||||
|
||||
resource "aws_lambda_function" "func" {
|
||||
filename = "test-fixtures/lambdatest.zip"
|
||||
function_name = "example_lambda_name"
|
||||
role = "${aws_iam_role.iam_for_lambda.arn}"
|
||||
handler = "exports.example"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "bucket" {
|
||||
bucket = "tf-test-bucket-%d"
|
||||
acl = "public-read"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_notification" "notification" {
|
||||
bucket = "${aws_s3_bucket.bucket.id}"
|
||||
lambda_function {
|
||||
id = "notification-lambda"
|
||||
lambda_function_arn = "${aws_lambda_function.func.arn}"
|
||||
events = [
|
||||
"s3:ObjectCreated:*",
|
||||
"s3:ObjectRemoved:Delete",
|
||||
]
|
||||
filter_prefix = "%d/"
|
||||
filter_suffix = ".png"
|
||||
}
|
||||
}
|
||||
`, randInt, randInt)
|
||||
}
|
||||
|
||||
func testAccAWSS3BucketConfigWithTopicNotificationWithoutFilter(randInt int) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "aws_sns_topic" "topic" {
|
||||
name = "terraform-test-topic"
|
||||
policy = <<POLICY
|
||||
{
|
||||
"Version":"2012-10-17",
|
||||
"Statement":[{
|
||||
"Sid": "",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS":"*"},
|
||||
"Action": "SNS:Publish",
|
||||
"Resource": "arn:aws:sns:*:*:terraform-test-topic",
|
||||
"Condition":{
|
||||
"ArnLike":{"aws:SourceArn":"${aws_s3_bucket.bucket.arn}"}
|
||||
}
|
||||
}]
|
||||
}
|
||||
POLICY
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "bucket" {
|
||||
bucket = "tf-test-bucket-%d"
|
||||
acl = "public-read"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_notification" "notification" {
|
||||
bucket = "${aws_s3_bucket.bucket.id}"
|
||||
topic {
|
||||
id = "notification-sns1"
|
||||
topic_arn = "${aws_sns_topic.topic.arn}"
|
||||
events = [
|
||||
"s3:ObjectCreated:*",
|
||||
"s3:ObjectRemoved:Delete",
|
||||
]
|
||||
}
|
||||
}
|
||||
`, randInt)
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_s3_bucket_notification"
|
||||
side_bar_current: "docs-aws-resource-s3-bucket-notification"
|
||||
description: |-
|
||||
Provides a S3 bucket notification resource.
|
||||
---
|
||||
|
||||
# aws\_s3\_bucket\_notification
|
||||
|
||||
Provides a S3 bucket notification resource.
|
||||
|
||||
## Example Usage
|
||||
|
||||
### Add notification configuration to SNS Topic
|
||||
|
||||
```
|
||||
resource "aws_sns_topic" "topic" {
|
||||
name = "s3-event-notification-topic"
|
||||
policy = <<POLICY
|
||||
{
|
||||
"Version":"2012-10-17",
|
||||
"Statement":[{
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS":"*"},
|
||||
"Action": "SNS:Publish",
|
||||
"Resource": "arn:aws:sns:*:*:s3-event-notification-topic",
|
||||
"Condition":{
|
||||
"ArnLike":{"aws:SourceArn":"${aws_s3_bucket.bucket.arn}"}
|
||||
}
|
||||
}]
|
||||
}
|
||||
POLICY
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "bucket" {
|
||||
bucket = "your_bucket_name"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_notification" "bucket_notification" {
|
||||
bucket = "${aws_s3_bucket.bucket.id}"
|
||||
topic {
|
||||
topic_arn = "${aws_sns_topic.topic.arn}"
|
||||
events = ["s3:ObjectCreated:*"]
|
||||
filter_suffix = ".log"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Add notification configuration to SQS Queue
|
||||
|
||||
```
|
||||
resource "aws_sqs_queue" "queue" {
|
||||
name = "s3-event-notification-queue"
|
||||
policy = <<POLICY
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": "*",
|
||||
"Action": "sqs:SendMessage",
|
||||
"Resource": "arn:aws:sqs:*:*:s3-event-notification-queue",
|
||||
"Condition": {
|
||||
"ArnEquals": { "aws:SourceArn": "${aws_s3_bucket.bucket.arn}" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
POLICY
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "bucket" {
|
||||
bucket = "your_bucket_name"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_notification" "bucket_notification" {
|
||||
bucket = "${aws_s3_bucket.bucket.id}"
|
||||
queue {
|
||||
queue_arn = "${aws_sqs_queue.queue.arn}"
|
||||
events = ["s3:ObjectCreated:*"]
|
||||
filter_suffix = ".log"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Add notification configuration to Lambda Function
|
||||
|
||||
```
|
||||
resource "aws_iam_role" "iam_for_lambda" {
|
||||
name = "iam_for_lambda"
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "lambda.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_lambda_permission" "allow_bucket" {
|
||||
statement_id = "AllowExecutionFromS3Bucket"
|
||||
action = "lambda:InvokeFunction"
|
||||
function_name = "${aws_lambda_function.func.arn}"
|
||||
principal = "s3.amazonaws.com"
|
||||
source_arn = "${aws_s3_bucket.bucket.arn}"
|
||||
}
|
||||
|
||||
resource "aws_lambda_function" "func" {
|
||||
filename = "your-function.zip"
|
||||
function_name = "example_lambda_name"
|
||||
role = "${aws_iam_role.iam_for_lambda.arn}"
|
||||
handler = "exports.example"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "bucket" {
|
||||
bucket = "your_bucket_name"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_notification" "bucket_notification" {
|
||||
bucket = "${aws_s3_bucket.bucket.id}"
|
||||
lambda_function {
|
||||
lambda_function_arn = "${aws_lambda_function.func.arn}"
|
||||
events = ["s3:ObjectCreated:*"]
|
||||
filter_prefix = "AWSLogs/"
|
||||
filter_suffix = ".log"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `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) The notification configuration to Lambda Function (documented below).
|
||||
|
||||
The `topic` notification configuration supports the following:
|
||||
|
||||
* `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.
|
||||
|
||||
The `queue` notification configuration supports the following:
|
||||
|
||||
* `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.
|
||||
|
||||
The `lambda_function` notification configuration supports the following:
|
||||
|
||||
* `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.
|
||||
|
|
@ -596,6 +596,10 @@
|
|||
<a href="/docs/providers/aws/r/s3_bucket_object.html">aws_s3_bucket_object</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-aws-resource-s3-bucket-notification") %>>
|
||||
<a href="/docs/providers/aws/r/s3_bucket_notification.html">aws_s3_bucket_notification</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
|
Loading…
Reference in New Issue