Skip to content

Commit

Permalink
Merge pull request #1737 from stack72/b-aws-ses-destination-1697
Browse files Browse the repository at this point in the history
resource/aws_ses_event_destination: Add support for SNS destinations
  • Loading branch information
radeksimko authored Jan 3, 2018
2 parents a5aa85f + b2e7a73 commit 91a1c6e
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 38 deletions.
53 changes: 39 additions & 14 deletions aws/resource_aws_ses_event_destination.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,26 @@ func resourceAwsSesEventDestination() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"name": &schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"configuration_set_name": &schema.Schema{
"configuration_set_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"enabled": &schema.Schema{
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
ForceNew: true,
},

"matching_types": &schema.Schema{
"matching_types": {
Type: schema.TypeSet,
Required: true,
ForceNew: true,
Expand All @@ -53,20 +53,21 @@ func resourceAwsSesEventDestination() *schema.Resource {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"kinesis_destination"},
MaxItems: 1,
ConflictsWith: []string{"kinesis_destination", "sns_destination"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"default_value": &schema.Schema{
"default_value": {
Type: schema.TypeString,
Required: true,
},

"dimension_name": &schema.Schema{
"dimension_name": {
Type: schema.TypeString,
Required: true,
},

"value_source": &schema.Schema{
"value_source": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateDimensionValueSource,
Expand All @@ -79,15 +80,32 @@ func resourceAwsSesEventDestination() *schema.Resource {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"cloudwatch_destination"},
MaxItems: 1,
ConflictsWith: []string{"cloudwatch_destination", "sns_destination"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"stream_arn": &schema.Schema{
"stream_arn": {
Type: schema.TypeString,
Required: true,
},

"role_arn": &schema.Schema{
"role_arn": {
Type: schema.TypeString,
Required: true,
},
},
},
},

"sns_destination": {
Type: schema.TypeSet,
MaxItems: 1,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"cloudwatch_destination", "kinesis_destination"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"topic_arn": {
Type: schema.TypeString,
Required: true,
},
Expand Down Expand Up @@ -125,9 +143,7 @@ func resourceAwsSesEventDestinationCreate(d *schema.ResourceData, meta interface

if v, ok := d.GetOk("kinesis_destination"); ok {
destination := v.(*schema.Set).List()
if len(destination) > 1 {
return fmt.Errorf("You can only define a single kinesis destination per record")
}

kinesis := destination[0].(map[string]interface{})
createOpts.EventDestination.KinesisFirehoseDestination = &ses.KinesisFirehoseDestination{
DeliveryStreamARN: aws.String(kinesis["stream_arn"].(string)),
Expand All @@ -136,6 +152,15 @@ func resourceAwsSesEventDestinationCreate(d *schema.ResourceData, meta interface
log.Printf("[DEBUG] Creating kinesis destination: %#v", kinesis)
}

if v, ok := d.GetOk("sns_destination"); ok {
destination := v.(*schema.Set).List()
sns := destination[0].(map[string]interface{})
createOpts.EventDestination.SNSDestination = &ses.SNSDestination{
TopicARN: aws.String(sns["topic_arn"].(string)),
}
log.Printf("[DEBUG] Creating sns destination: %#v", sns)
}

_, err := conn.CreateConfigurationSetEventDestination(createOpts)
if err != nil {
return fmt.Errorf("Error creating SES configuration set event destination: %s", err)
Expand Down
81 changes: 57 additions & 24 deletions aws/resource_aws_ses_event_destination_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ import (
)

func TestAccAWSSESEventDestination_basic(t *testing.T) {
rString := acctest.RandString(8)

bucketName := fmt.Sprintf("tf-acc-bucket-ses-event-dst-%s", rString)
roleName := fmt.Sprintf("tf_acc_role_ses_event_dst_%s", rString)
streamName := fmt.Sprintf("tf_acc_stream_ses_event_dst_%s", rString)
policyName := fmt.Sprintf("tf_acc_policy_ses_event_dst_%s", rString)
topicName := fmt.Sprintf("tf_acc_topic_ses_event_dst_%s", rString)
sesCfgSetName := fmt.Sprintf("tf_acc_cfg_ses_event_dst_%s", rString)
sesEventDstNameKinesis := fmt.Sprintf("tf_acc_event_dst_kinesis_%s", rString)
sesEventDstNameCw := fmt.Sprintf("tf_acc_event_dst_cloudwatch_%s", rString)
sesEventDstNameSns := fmt.Sprintf("tf_acc_event_dst_sns_%s", rString)

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
Expand All @@ -19,13 +31,16 @@ func TestAccAWSSESEventDestination_basic(t *testing.T) {
CheckDestroy: testAccCheckSESEventDestinationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSSESEventDestinationConfig,
Config: testAccAWSSESEventDestinationConfig(bucketName, roleName, streamName, policyName, topicName,
sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsSESEventDestinationExists("aws_ses_configuration_set.test"),
resource.TestCheckResourceAttr(
"aws_ses_event_destination.kinesis", "name", "event-destination-kinesis"),
"aws_ses_event_destination.kinesis", "name", sesEventDstNameKinesis),
resource.TestCheckResourceAttr(
"aws_ses_event_destination.cloudwatch", "name", sesEventDstNameCw),
resource.TestCheckResourceAttr(
"aws_ses_event_destination.cloudwatch", "name", "event-destination-cloudwatch"),
"aws_ses_event_destination.sns", "name", sesEventDstNameSns),
),
},
},
Expand All @@ -47,7 +62,7 @@ func testAccCheckSESEventDestinationDestroy(s *terraform.State) error {

found := false
for _, element := range response.ConfigurationSets {
if *element.Name == fmt.Sprintf("some-configuration-set-%d", edRandomInteger) {
if *element.Name == rs.Primary.ID {
found = true
}
}
Expand Down Expand Up @@ -82,7 +97,7 @@ func testAccCheckAwsSESEventDestinationExists(n string) resource.TestCheckFunc {

found := false
for _, element := range response.ConfigurationSets {
if *element.Name == fmt.Sprintf("some-configuration-set-%d", edRandomInteger) {
if *element.Name == rs.Primary.ID {
found = true
}
}
Expand All @@ -95,15 +110,16 @@ func testAccCheckAwsSESEventDestinationExists(n string) resource.TestCheckFunc {
}
}

var edRandomInteger = acctest.RandInt()
var testAccAWSSESEventDestinationConfig = fmt.Sprintf(`
func testAccAWSSESEventDestinationConfig(bucketName, roleName, streamName, policyName, topicName,
sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns string) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
bucket = "tf-test-bucket-format"
bucket = "%s"
acl = "private"
}
resource "aws_iam_role" "firehose_role" {
name = "firehose_test_role_test"
name = "%s"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
Expand All @@ -129,7 +145,7 @@ EOF
}
resource "aws_kinesis_firehose_delivery_stream" "test_stream" {
name = "terraform-kinesis-firehose-test-stream-test"
name = "%s"
destination = "s3"
s3_configuration {
role_arn = "${aws_iam_role.firehose_role.arn}"
Expand All @@ -138,7 +154,7 @@ resource "aws_kinesis_firehose_delivery_stream" "test_stream" {
}
resource "aws_iam_role_policy" "firehose_delivery_policy" {
name = "tf-delivery-policy-test"
name = "%s"
role = "${aws_iam_role.firehose_role.id}"
policy = "${data.aws_iam_policy_document.fh_felivery_document.json}"
}
Expand All @@ -156,32 +172,49 @@ data "aws_iam_policy_document" "fh_felivery_document" {
}
}
resource "aws_sns_topic" "ses_destination" {
name = "%s"
}
resource "aws_ses_configuration_set" "test" {
name = "some-configuration-set-%d"
name = "%s"
}
resource "aws_ses_event_destination" "kinesis" {
name = "event-destination-kinesis",
configuration_set_name = "${aws_ses_configuration_set.test.name}",
enabled = true,
matching_types = ["bounce", "send"],
name = "%s"
configuration_set_name = "${aws_ses_configuration_set.test.name}"
enabled = true
matching_types = ["bounce", "send"]
kinesis_destination = {
stream_arn = "${aws_kinesis_firehose_delivery_stream.test_stream.arn}",
kinesis_destination {
stream_arn = "${aws_kinesis_firehose_delivery_stream.test_stream.arn}"
role_arn = "${aws_iam_role.firehose_role.arn}"
}
}
resource "aws_ses_event_destination" "cloudwatch" {
name = "event-destination-cloudwatch",
configuration_set_name = "${aws_ses_configuration_set.test.name}",
enabled = true,
matching_types = ["bounce", "send"],
name = "%s",
configuration_set_name = "${aws_ses_configuration_set.test.name}"
enabled = true
matching_types = ["bounce", "send"]
cloudwatch_destination = {
cloudwatch_destination {
default_value = "default"
dimension_name = "dimension"
value_source = "emailHeader"
}
}
`, edRandomInteger)
resource "aws_ses_event_destination" "sns" {
name = "%s"
configuration_set_name = "${aws_ses_configuration_set.test.name}"
enabled = true
matching_types = ["bounce", "send"]
sns_destination {
topic_arn = "${aws_sns_topic.ses_destination.arn}"
}
}
`, bucketName, roleName, streamName, policyName, topicName,
sesCfgSetName, sesEventDstNameKinesis, sesEventDstNameCw, sesEventDstNameSns)
}
5 changes: 5 additions & 0 deletions website/docs/r/ses_event_destination.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ The following arguments are supported:
* `matching_types` - (Required) A list of matching types. May be any of `"send"`, `"reject"`, `"bounce"`, `"complaint"`, `"delivery"`, `"open"`, or `"click"`.
* `cloudwatch_destination` - (Optional) CloudWatch destination for the events
* `kinesis_destination` - (Optional) Send the events to a kinesis firehose destination
* `sns_destination` - (Optional) Send the events to an SNS Topic destination

~> **NOTE:** You can specify `"cloudwatch_destination"` or `"kinesis_destination"` but not both

Expand All @@ -65,3 +66,7 @@ Kinesis Destination requires the following:
* `stream_arn` - (Required) The ARN of the Kinesis Stream
* `role_arn` - (Required) The ARN of the role that has permissions to access the Kinesis Stream

SNS Topic requires the following:

* `topic_arn` - (Required) The ARN of the SNS topic

0 comments on commit 91a1c6e

Please sign in to comment.