From 1866fbf1d85b4c8d4078b1927ff420a8c2a5b889 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Fri, 22 Jan 2021 12:10:01 +0000 Subject: [PATCH 01/11] adds schema for deadletterconfig and retry policy --- aws/resource_aws_cloudwatch_event_target.go | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index 28e6ff5199c..2668eec1feb 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -248,6 +248,36 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { }, }, }, + + "retry_policy": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "maximum_event_age_in_seconds": { + Type: schema.TypeInt, + Optional: true, + }, + "maximum_retry_attempts": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + + "dead_letter_config": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + }, }, } } From 42e0f2f357da2082b3d04cf4e59e42814712b261 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Fri, 22 Jan 2021 12:42:47 +0000 Subject: [PATCH 02/11] adds functions to parse new params --- aws/resource_aws_cloudwatch_event_target.go | 59 +++++++++++++++++---- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index 2668eec1feb..bc074567354 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -264,16 +264,16 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { }, }, }, + }, - "dead_letter_config": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "arn": { - Type: schema.TypeString, - Optional: true, - }, + "dead_letter_config": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Optional: true, }, }, }, @@ -464,6 +464,14 @@ func buildPutTargetInputStruct(d *schema.ResourceData) *events.PutTargetsInput { e.InputTransformer = expandAwsCloudWatchEventTransformerParameters(v.([]interface{})) } + if v, ok := d.GetOk("retry_policy"); ok { + e.RetryPolicy = expandAwsCloudWatchEventRetryPolicyParameters(v.([]interface{})) + } + + if v, ok := d.GetOk("dead_letter_config"); ok { + e.DeadLetterConfig = expandAwsCloudWatchEventDeadLetterConfigParameters(v.([]interface{})) + } + input := events.PutTargetsInput{ Rule: aws.String(d.Get("rule").(string)), Targets: []*events.Target{e}, @@ -515,6 +523,39 @@ func expandAwsCloudWatchEventTargetEcsParameters(config []interface{}) *events.E return ecsParameters } + +func expandAwsCloudWatchEventRetryPolicyParameters(rp []interface{}) *events.RetryPolicy { + retryPolicy := &events.RetryPolicy{} + + for _, v := range rp { + params := v.(map[string]interface{}) + + if val, ok := params["maximum_event_age_in_seconds"]; ok { + retryPolicy.MaximumEventAgeInSeconds = aws.Int64(int64(params["maximum_event_age_in_seconds"].(int))) + } + + if val, ok := params["maximum_retry_attempts"]; ok { + retryPolicy.MaximumRetryAttempts = aws.Int64(int64(params["maximum_retry_attempts"].(int))) + } + } + + return retryPolicy +} + +func expandAwsCloudWatchEventDeadLetterConfigParameters(dlp []interface{}) *events.DeadLetterConfig { + deadLetterConfig := &events.DeadLetterConfig{} + + for _, v := range dlp { + params := v.(map[string]interface{}) + + if val, ok := params["arn"].(string); ok && val != "" { + deadLetterConfig.Arn = aws.String(val) + } + } + + return deadLetterConfig +} + func expandAwsCloudWatchEventTargetEcsParametersNetworkConfiguration(nc []interface{}) *events.NetworkConfiguration { if len(nc) == 0 { return nil From a1789eac0ef92bd981484cd7b46c6a73bea961f4 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Fri, 22 Jan 2021 12:49:23 +0000 Subject: [PATCH 03/11] use defined vars instead of using map --- aws/resource_aws_cloudwatch_event_target.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index bc074567354..e38a150a2c5 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -530,12 +530,12 @@ func expandAwsCloudWatchEventRetryPolicyParameters(rp []interface{}) *events.Ret for _, v := range rp { params := v.(map[string]interface{}) - if val, ok := params["maximum_event_age_in_seconds"]; ok { - retryPolicy.MaximumEventAgeInSeconds = aws.Int64(int64(params["maximum_event_age_in_seconds"].(int))) + if val, ok := params["maximum_event_age_in_seconds"].(int); ok { + retryPolicy.MaximumEventAgeInSeconds = aws.Int64(int64(val)) } - if val, ok := params["maximum_retry_attempts"]; ok { - retryPolicy.MaximumRetryAttempts = aws.Int64(int64(params["maximum_retry_attempts"].(int))) + if val, ok := params["maximum_retry_attempts"].(int); ok { + retryPolicy.MaximumRetryAttempts = aws.Int64(int64(val)) } } From 4ec11880ec52eabee0741a39b2e74d64ce4ccbc7 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Fri, 22 Jan 2021 13:19:19 +0000 Subject: [PATCH 04/11] adds validation --- aws/resource_aws_cloudwatch_event_target.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index e38a150a2c5..ccca18737a5 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -255,8 +255,9 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "maximum_event_age_in_seconds": { - Type: schema.TypeInt, - Optional: true, + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(60), }, "maximum_retry_attempts": { Type: schema.TypeInt, @@ -272,8 +273,9 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "arn": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateArn, }, }, }, From 67813f0e4ca74109260f313a7983d7a039f27e72 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Wed, 27 Jan 2021 12:45:03 +0000 Subject: [PATCH 05/11] adds a test for the new fields for retry_policy and dead_letter_config --- ...source_aws_cloudwatch_event_target_test.go | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index c6d3e17a84e..c341e3d193b 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -247,6 +247,39 @@ func TestAccAWSCloudWatchEventTarget_GeneratedTargetId(t *testing.T) { }) } +func TestAccAWSCloudWatchEventTarget_retrypolicy_dlc(t *testing.T) { + resourceName := "aws_cloudwatch_event_target.test" + kinesisStreamResourceName := "aws_kinesis_stream.test" + queueResourceName := "aws_sqs_queue.test" + var v events.Target + + ruleName := acctest.RandomWithPrefix("tf-acc-cw-event-rule-full") + ssmDocumentName := acctest.RandomWithPrefix("tf_ssm_Document") + targetID := acctest.RandomWithPrefix("tf-acc-cw-target-full") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudWatchEventTargetConfig_retrypolicy_dlc(ruleName, targetID, ssmDocumentName), + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventTargetExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "rule", ruleName), + resource.TestCheckResourceAttr(resourceName, "target_id", targetID), + resource.TestCheckResourceAttrPair(resourceName, "arn", kinesisStreamResourceName, "arn"), + testAccCheckResourceAttrEquivalentJSON(resourceName, "input", `{"source": ["aws.cloudtrail"]}`), + resource.TestCheckResourceAttr(resourceName, "input_path", ""), + resource.TestCheckResourceAttr(resourceName, "retry_policy.0.maximum_event_age_in_seconds", "60"), + resource.TestCheckResourceAttr(resourceName, "retry_policy.0.maximum_retry_attempts", "5"), + resource.TestCheckResourceAttrPair(resourceName, "dead_letter_config.0.arn", queueResourceName, "arn"), + ), + }, + }, + }) +} + func TestAccAWSCloudWatchEventTarget_full(t *testing.T) { resourceName := "aws_cloudwatch_event_target.test" kinesisStreamResourceName := "aws_kinesis_stream.test" @@ -626,6 +659,8 @@ func testAccAWSCloudWatchEventTargetImportStateIdFunc(resourceName string) resou return "", fmt.Errorf("Not found: %s", resourceName) } + fmt.Printf("%#v", rs.Primary.Attributes) + return fmt.Sprintf("%s/%s/%s", rs.Primary.Attributes["event_bus_name"], rs.Primary.Attributes["rule"], rs.Primary.Attributes["target_id"]), nil } } @@ -730,6 +765,89 @@ resource "aws_sns_topic" "test" { `, ruleName, snsTopicName) } +func testAccAWSCloudWatchEventTargetConfig_retrypolicy_dlc(ruleName, targetName, rName string) string { + return fmt.Sprintf(` +resource "aws_cloudwatch_event_rule" "test" { + name = %[1]q + schedule_expression = "rate(1 hour)" + role_arn = aws_iam_role.test.arn +} + +resource "aws_iam_role" "test" { + name = %[2]q + + assume_role_policy = < Date: Wed, 27 Jan 2021 15:10:08 +0000 Subject: [PATCH 06/11] fixes fmt --- aws/resource_aws_cloudwatch_event_target_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index c341e3d193b..73ee8034cd7 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -768,9 +768,9 @@ resource "aws_sns_topic" "test" { func testAccAWSCloudWatchEventTargetConfig_retrypolicy_dlc(ruleName, targetName, rName string) string { return fmt.Sprintf(` resource "aws_cloudwatch_event_rule" "test" { - name = %[1]q - schedule_expression = "rate(1 hour)" - role_arn = aws_iam_role.test.arn + name = %[1]q + schedule_expression = "rate(1 hour)" + role_arn = aws_iam_role.test.arn } resource "aws_iam_role" "test" { @@ -831,12 +831,12 @@ INPUT retry_policy { maximum_event_age_in_seconds = 60 - maximum_retry_attempts = 5 + maximum_retry_attempts = 5 } - dead_letter_config { - arn = aws_sqs_queue.test.arn - } + dead_letter_config { + arn = aws_sqs_queue.test.arn + } } resource "aws_kinesis_stream" "test" { From 37fd23fe327a269568c51d5852be39cac1ab0ba7 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Wed, 27 Jan 2021 15:39:24 +0000 Subject: [PATCH 07/11] updates docs to detail the new schema options --- website/docs/r/cloudwatch_event_target.html.markdown | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/website/docs/r/cloudwatch_event_target.html.markdown b/website/docs/r/cloudwatch_event_target.html.markdown index afef8c36bd9..bb2d76f1480 100644 --- a/website/docs/r/cloudwatch_event_target.html.markdown +++ b/website/docs/r/cloudwatch_event_target.html.markdown @@ -307,6 +307,8 @@ The following arguments are supported: * `kinesis_target` - (Optional) Parameters used when you are using the rule to invoke an Amazon Kinesis Stream. Documented below. A maximum of 1 are allowed. * `sqs_target` - (Optional) Parameters used when you are using the rule to invoke an Amazon SQS Queue. Documented below. A maximum of 1 are allowed. * `input_transformer` - (Optional) Parameters used when you are providing a custom input to a target based on certain event data. Conflicts with `input` and `input_path`. +* `retry_policy` - (Optional) Parameters used when you are providing retry policies. Documented below. A maximum of 1 are allowed. +* `dead_letter_config` - (Optional) Parameters used when you are providing a dead letter conifg. Documented below. A maximum of 1 are allowed. `run_command_targets` support the following: @@ -354,6 +356,15 @@ For more information, see [Task Networking](https://docs.aws.amazon.com/AmazonEC * `input_template` - (Required) Template to customize data sent to the target. Must be valid JSON. To send a string value, the string value must include double quotes. Values must be escaped for both JSON and Terraform, e.g. `"\"Your string goes here.\\nA new line.\""` +`retry_policy` support the following: + +* `maximum_event_age_in_seconds` - (Optional) The age in seconds to continue to make retry attempts. +* `maximum_retry_attempts` - (Optional) maximum number of retry attempts to make before the request fails + +`dead_letter_config` support the following: + +* `arn` - (Optional) - ARN of the SQS queue specified as the target for the dead-letter queue. + ## Import EventBridge Targets can be imported using `event_bus_name/rule-name/target-id` (if you omit `event_bus_name`, the `default` event bus will be used). From 7a88e2b3b68d3b5205f9a2142066420ea9c4e845 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Wed, 27 Jan 2021 15:44:29 +0000 Subject: [PATCH 08/11] sets maxitems to 1 for new schema options --- aws/resource_aws_cloudwatch_event_target.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index ccca18737a5..059460ce835 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -252,6 +252,7 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { "retry_policy": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "maximum_event_age_in_seconds": { @@ -270,6 +271,7 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { "dead_letter_config": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "arn": { From f82bd02a01565a1dc24858062bc43c25af9ec4bf Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Thu, 18 Feb 2021 11:00:30 +0000 Subject: [PATCH 09/11] Adds read functions to support DeadLetterConfig and RetryPolicy --- aws/resource_aws_cloudwatch_event_target.go | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index 059460ce835..a895d74bf5a 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -384,6 +384,18 @@ func resourceAwsCloudWatchEventTargetRead(d *schema.ResourceData, meta interface } } + if t.RetryPolicy != nil { + if err := d.Set("retry_policy", flatternAwsCloudWatchEventTargetRetryPolicy(t.RetryPolicy)); err != nil { + return fmt.Errorf("Error setting retry_policy error: #{err}") + } + } + + if t.DeadLetterConfig != nil { + if err := d.Set("dead_letter_config", flatternAwsCloudWatchEventTargetDeadLetterConfig(t.DeadLetterConfig)); err != nil { + return fmt.Errorf("Error setting dead_letter_config error: #{err}") + } + } + return nil } @@ -733,6 +745,25 @@ func flattenAwsCloudWatchInputTransformer(inputTransformer *events.InputTransfor return result } +func flatternAwsCloudWatchEventTargetRetryPolicy(rp *events.RetryPolicy) []map[string]interface{} { + config := make(map[string]interface{}) + + config["maximum_event_age_in_seconds"] = aws.Int64Value(rp.MaximumEventAgeInSeconds) + config["maximum_retry_attempts"] = aws.Int64Value(rp.MaximumRetryAttempts) + + result := []map[string]interface{}{config} + return result +} + +func flatternAwsCloudWatchEventTargetDeadLetterConfig(dlc *events.DeadLetterConfig) []map[string]interface{} { + config := make(map[string]interface{}) + + config["arn"] = aws.StringValue(dlc.Arn) + + result := []map[string]interface{}{config} + return result +} + func resourceAwsCloudWatchEventTargetImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { busName, ruleName, targetID, err := tfevents.TargetParseImportID(d.Id()) if err != nil { From 5bc60c99cc14af58d96d5f89e6fa31cf643cba9d Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Thu, 18 Feb 2021 11:01:06 +0000 Subject: [PATCH 10/11] fixes case issues within tests --- aws/resource_aws_cloudwatch_event_target_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index 73ee8034cd7..f258ded59aa 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -247,7 +247,7 @@ func TestAccAWSCloudWatchEventTarget_GeneratedTargetId(t *testing.T) { }) } -func TestAccAWSCloudWatchEventTarget_retrypolicy_dlc(t *testing.T) { +func TestAccAWSCloudWatchEventTarget_RetryPolicy_DeadLetterConfig(t *testing.T) { resourceName := "aws_cloudwatch_event_target.test" kinesisStreamResourceName := "aws_kinesis_stream.test" queueResourceName := "aws_sqs_queue.test" @@ -263,7 +263,7 @@ func TestAccAWSCloudWatchEventTarget_retrypolicy_dlc(t *testing.T) { CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudWatchEventTargetConfig_retrypolicy_dlc(ruleName, targetID, ssmDocumentName), + Config: testAccAWSCloudWatchEventTargetConfig_retryPolicyDlc(ruleName, targetID, ssmDocumentName), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventTargetExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "rule", ruleName), @@ -765,7 +765,7 @@ resource "aws_sns_topic" "test" { `, ruleName, snsTopicName) } -func testAccAWSCloudWatchEventTargetConfig_retrypolicy_dlc(ruleName, targetName, rName string) string { +func testAccAWSCloudWatchEventTargetConfig_retryPolicyDlc(ruleName, targetName, rName string) string { return fmt.Sprintf(` resource "aws_cloudwatch_event_rule" "test" { name = %[1]q From 733d4ce0ef72841a0b9ea3b5fb24c0581338cfd1 Mon Sep 17 00:00:00 2001 From: Simon Thulbourn Date: Thu, 18 Feb 2021 11:10:51 +0000 Subject: [PATCH 11/11] adds changelog entry --- .changelog/17241.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/17241.txt diff --git a/.changelog/17241.txt b/.changelog/17241.txt new file mode 100644 index 00000000000..cc726257b85 --- /dev/null +++ b/.changelog/17241.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/aws_cloudwatch_event_target: Adds `retry_policy` attributes +``` + +```release-note:enhancement +resource/aws_cloudwatch_event_target: Adds `dead_letter_config` attributes +``` \ No newline at end of file