From 7855810304ff9804a589ca5c4d64198ec8fec4fb Mon Sep 17 00:00:00 2001 From: Richard Owen <1186519+richardowen@users.noreply.github.com> Date: Thu, 22 Jul 2021 09:20:57 +0100 Subject: [PATCH 01/26] Delete dependabot.yml --- .github/dependabot.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 9d24fb90511d..000000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,31 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - - package-ecosystem: "gomod" - directory: "/" - ignore: - - dependency-name: "golang.org/x/tools" - - dependency-name: "google.golang.org/grpc" - schedule: - interval: "daily" - - package-ecosystem: "gomod" - directory: "/awsproviderlint" - ignore: - - dependency-name: "golang.org/x/tools" - - dependency-name: "google.golang.org/grpc" - schedule: - interval: "daily" - - package-ecosystem: "gomod" - directory: "/tools" - ignore: - - dependency-name: "golang.org/x/tools" - - dependency-name: "google.golang.org/grpc" - schedule: - interval: "daily" - - package-ecosystem: "terraform" - directory: "/infrastructure/repository" - schedule: - interval: "daily" From cb7fa830ba9f78cab12b436fdbca379c4cba1150 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Fri, 23 Jul 2021 15:03:43 +0100 Subject: [PATCH 02/26] Add acceptance test for AWS EventBridge event bus configuration using an ARN as event_bus_name. --- ...resource_aws_cloudwatch_event_rule_test.go | 41 +++++++++++++++++++ docs/MAINTAINING.md | 1 + 2 files changed, 42 insertions(+) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index 446c0eb781ae..8dc18a985b88 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -531,6 +531,47 @@ func TestAccAWSCloudWatchEventRule_PartnerEventBus(t *testing.T) { }) } +func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { + key := "EVENT_BRIDGE_EVENT_BUS_ARN" + busName := os.Getenv(key) + if busName == "" { + t.Skipf("Environment variable %s is not set", key) + } + + var v events.DescribeRuleOutput + rName := acctest.RandomWithPrefix("tf-acc-test-rule") + resourceName := "aws_cloudwatch_event_rule.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudWatchEventRulePartnerEventBusConfig(rName, busName), + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventRuleExists(resourceName, &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s$`, busName, rName))), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "event_bus_name", busName), + testAccCheckResourceAttrEquivalentJSON(resourceName, "event_pattern", "{\"source\":[\"aws.ec2\"]}"), + resource.TestCheckResourceAttr(resourceName, "is_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "role_arn", ""), + resource.TestCheckResourceAttr(resourceName, "schedule_expression", ""), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckCloudWatchEventRuleExists(n string, rule *events.DescribeRuleOutput) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] diff --git a/docs/MAINTAINING.md b/docs/MAINTAINING.md index 7495f92854cc..3556d0da7a70 100644 --- a/docs/MAINTAINING.md +++ b/docs/MAINTAINING.md @@ -392,6 +392,7 @@ Environment variables (beyond standard AWS Go SDK ones) used by acceptance testi | `DX_VIRTUAL_INTERFACE_ID` | Identifier for Direct Connect Virtual Interface testing. | | `EC2_SECURITY_GROUP_RULES_PER_GROUP_LIMIT` | EC2 Quota for Rules per Security Group. Defaults to 50. **DEPRECATED:** Can be augmented or replaced with Service Quotas lookup. | | `EVENT_BRIDGE_PARTNER_EVENT_BUS_NAME` | Amazon EventBridge partner event bus name. | +| `EVENT_BRIDGE_EVENT_BUS_ARN` | Amazon EventBridge event bus ARN. | | `EVENT_BRIDGE_PARTNER_EVENT_SOURCE_NAME` | Amazon EventBridge partner event source name. | | `GCM_API_KEY` | API Key for Google Cloud Messaging in Pinpoint and SNS Platform Application testing. | | `GITHUB_TOKEN` | GitHub token for CodePipeline testing. | From d43189fe39bfd2cf6bfd43dcd16a048d06c4d6e5 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Fri, 23 Jul 2021 15:32:30 +0100 Subject: [PATCH 03/26] EventBridge event bus rule, READ operation: update rule ID validation to accept event bus ARN. --- aws/internal/service/cloudwatchevents/id.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aws/internal/service/cloudwatchevents/id.go b/aws/internal/service/cloudwatchevents/id.go index 7d383458c5a8..4da4fc130d48 100644 --- a/aws/internal/service/cloudwatchevents/id.go +++ b/aws/internal/service/cloudwatchevents/id.go @@ -4,6 +4,8 @@ import ( "fmt" "regexp" "strings" + + awsarn "github.com/aws/aws-sdk-go/aws/arn" ) var ( @@ -54,7 +56,7 @@ func RuleParseID(id string) (string, string, error) { i := strings.LastIndex(id, ruleIDSeparator) busName := id[:i] statementID := id[i+1:] - if partnerEventBusPattern.MatchString(busName) && statementID != "" { + if (partnerEventBusPattern.MatchString(busName) || awsarn.IsARN(busName)) && statementID != "" { return busName, statementID, nil } } From 2f3116169d292a89a89c5ec9da5abbf3bfff5e03 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Fri, 23 Jul 2021 16:38:25 +0100 Subject: [PATCH 04/26] Fix TestAccAWSCloudWatchEventRule_EventBusArn test. --- aws/resource_aws_cloudwatch_event_rule_test.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index 8dc18a985b88..9b092809e77f 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -5,9 +5,11 @@ import ( "log" "os" "regexp" + "strings" "testing" "github.com/aws/aws-sdk-go/aws" + awsarn "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/cloudwatchevents" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/go-multierror" @@ -533,10 +535,11 @@ func TestAccAWSCloudWatchEventRule_PartnerEventBus(t *testing.T) { func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { key := "EVENT_BRIDGE_EVENT_BUS_ARN" - busName := os.Getenv(key) - if busName == "" { - t.Skipf("Environment variable %s is not set", key) + busArn, err := awsarn.Parse(os.Getenv(key)) + if err != nil { + t.Skipf("Environment variable %s is missing or is not a valid ARN", key) } + busName := strings.Replace(busArn.Resource, "event-bus/", "", 1) var v events.DescribeRuleOutput rName := acctest.RandomWithPrefix("tf-acc-test-rule") @@ -549,12 +552,12 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudWatchEventRulePartnerEventBusConfig(rName, busName), + Config: testAccAWSCloudWatchEventRulePartnerEventBusConfig(rName, busArn.String()), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventRuleExists(resourceName, &v), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s$`, busName, rName))), resource.TestCheckResourceAttr(resourceName, "description", ""), - resource.TestCheckResourceAttr(resourceName, "event_bus_name", busName), + resource.TestCheckResourceAttr(resourceName, "event_bus_name", busArn.String()), testAccCheckResourceAttrEquivalentJSON(resourceName, "event_pattern", "{\"source\":[\"aws.ec2\"]}"), resource.TestCheckResourceAttr(resourceName, "is_enabled", "true"), resource.TestCheckResourceAttr(resourceName, "name", rName), From 3cdda95583289051e185a710344f3aeb2690c753 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Fri, 23 Jul 2021 17:10:38 +0100 Subject: [PATCH 05/26] Update READ function for event bus rule to preserve event bus ARNs. --- aws/resource_aws_cloudwatch_event_rule.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudwatch_event_rule.go b/aws/resource_aws_cloudwatch_event_rule.go index a3c3f2d263bf..934932317830 100644 --- a/aws/resource_aws_cloudwatch_event_rule.go +++ b/aws/resource_aws_cloudwatch_event_rule.go @@ -6,6 +6,7 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" + awsarn "github.com/aws/aws-sdk-go/aws/arn" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -180,7 +181,14 @@ func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{} d.Set("name_prefix", naming.NamePrefixFromName(aws.StringValue(out.Name))) d.Set("role_arn", out.RoleArn) d.Set("schedule_expression", out.ScheduleExpression) - d.Set("event_bus_name", out.EventBusName) + currentEventBusName := d.Get("event_bus_name").(string) + if awsarn.IsARN(currentEventBusName) { + eventBusArn, _ := awsarn.Parse(currentEventBusName) + eventBusArn.Resource = "event-bus/" + *out.EventBusName + d.Set("event_bus_name", eventBusArn.String()) + } else { + d.Set("event_bus_name", out.EventBusName) + } boolState, err := getBooleanStateFromString(*out.State) if err != nil { From 1a687b8cea07515fc5676e75e7e8b2348a5d12e9 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Mon, 26 Jul 2021 14:57:18 +0100 Subject: [PATCH 06/26] Don't import event bus rule on test. --- aws/resource_aws_cloudwatch_event_rule_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index 9b092809e77f..53e8bd38ff5e 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -566,11 +566,6 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, }, }) } From 2e157d238de8cd6448be3b610089606d1a460866 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Mon, 26 Jul 2021 16:25:11 +0100 Subject: [PATCH 07/26] Reintroduce import tests for event bus rule. --- .../service/cloudwatchevents/finder/finder.go | 12 +++++++++++- aws/resource_aws_cloudwatch_event_rule.go | 10 +--------- aws/resource_aws_cloudwatch_event_rule_test.go | 5 +++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/aws/internal/service/cloudwatchevents/finder/finder.go b/aws/internal/service/cloudwatchevents/finder/finder.go index 408979e14e77..c270732ddb0e 100644 --- a/aws/internal/service/cloudwatchevents/finder/finder.go +++ b/aws/internal/service/cloudwatchevents/finder/finder.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/aws/aws-sdk-go/aws" + awsarn "github.com/aws/aws-sdk-go/aws/arn" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -47,7 +48,16 @@ func Rule(conn *events.CloudWatchEvents, eventBusName, ruleName string) (*events input.EventBusName = aws.String(eventBusName) } - return conn.DescribeRule(&input) + out, err := conn.DescribeRule(&input) + + if err == nil && awsarn.IsARN(eventBusName) { + eventBusArn, _ := awsarn.Parse(eventBusName) + eventBusArn.Resource = "event-bus/" + *out.EventBusName + updatedEventBusArn := eventBusArn.String() + out.EventBusName = &updatedEventBusArn + } + + return out, err } diff --git a/aws/resource_aws_cloudwatch_event_rule.go b/aws/resource_aws_cloudwatch_event_rule.go index 934932317830..a3c3f2d263bf 100644 --- a/aws/resource_aws_cloudwatch_event_rule.go +++ b/aws/resource_aws_cloudwatch_event_rule.go @@ -6,7 +6,6 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - awsarn "github.com/aws/aws-sdk-go/aws/arn" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -181,14 +180,7 @@ func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{} d.Set("name_prefix", naming.NamePrefixFromName(aws.StringValue(out.Name))) d.Set("role_arn", out.RoleArn) d.Set("schedule_expression", out.ScheduleExpression) - currentEventBusName := d.Get("event_bus_name").(string) - if awsarn.IsARN(currentEventBusName) { - eventBusArn, _ := awsarn.Parse(currentEventBusName) - eventBusArn.Resource = "event-bus/" + *out.EventBusName - d.Set("event_bus_name", eventBusArn.String()) - } else { - d.Set("event_bus_name", out.EventBusName) - } + d.Set("event_bus_name", out.EventBusName) boolState, err := getBooleanStateFromString(*out.State) if err != nil { diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index 53e8bd38ff5e..9b092809e77f 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -566,6 +566,11 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } From 827a419441ec8025d410b6a28bea755841246525 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Mon, 26 Jul 2021 18:05:26 +0100 Subject: [PATCH 08/26] Allow for setting event_bus_name as ARN for aws_cloudwatch_event_target. --- aws/internal/service/cloudwatchevents/id.go | 2 +- ...source_aws_cloudwatch_event_target_test.go | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/aws/internal/service/cloudwatchevents/id.go b/aws/internal/service/cloudwatchevents/id.go index 4da4fc130d48..5a9d8b2bc723 100644 --- a/aws/internal/service/cloudwatchevents/id.go +++ b/aws/internal/service/cloudwatchevents/id.go @@ -92,7 +92,7 @@ func TargetParseImportID(id string) (string, string, string, error) { iRule := strings.LastIndex(id[:iTarget], targetImportIDSeparator) busName := id[:iRule] ruleName := id[iRule+1 : iTarget] - if partnerEventBusPattern.MatchString(busName) && ruleName != "" && targetID != "" { + if (partnerEventBusPattern.MatchString(busName) || awsarn.IsARN(busName)) && ruleName != "" && targetID != "" { return busName, ruleName, targetID, nil } } diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index c9f24746c60b..79714f1b0d24 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + awsarn "github.com/aws/aws-sdk-go/aws/arn" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -219,6 +220,45 @@ func TestAccAWSCloudWatchEventTarget_EventBusName(t *testing.T) { }) } +func TestAccAWSCloudWatchEventTarget_EventBusArn(t *testing.T) { + resourceName := "aws_cloudwatch_event_target.test" + key := "EVENT_BRIDGE_EVENT_BUS_ARN" + busArn, err := awsarn.Parse(os.Getenv(key)) + if err != nil { + t.Skipf("Environment variable %s is missing or is not a valid ARN", key) + } + busName := strings.Replace(busArn.Resource, "event-bus/", "", 1) + + var target events.Target + ruleName := acctest.RandomWithPrefix("tf-acc-test-rule") + snsTopicName := acctest.RandomWithPrefix("tf-acc-test-sns") + targetID := acctest.RandomWithPrefix("tf-acc-test-target") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudWatchEventTargetConfigEventBusName(ruleName, busName, snsTopicName, targetID), + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchEventTargetExists(resourceName, &target), + resource.TestCheckResourceAttr(resourceName, "rule", ruleName), + resource.TestCheckResourceAttr(resourceName, "event_bus_name", busName), + resource.TestCheckResourceAttr(resourceName, "target_id", targetID), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccAWSCloudWatchEventTargetImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAWSCloudWatchEventTarget_GeneratedTargetId(t *testing.T) { resourceName := "aws_cloudwatch_event_target.test" snsTopicResourceName := "aws_sns_topic.test" @@ -945,6 +985,37 @@ resource "aws_cloudwatch_event_bus" "test" { `, targetID, snsTopicName, ruleName, eventBusName) } +func testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, eventBusName, snsTopicName, targetID string) string { + return fmt.Sprintf(` +resource "aws_cloudwatch_event_target" "test" { + rule = aws_cloudwatch_event_rule.test.name + event_bus_name = aws_cloudwatch_event_rule.test.event_bus_name + target_id = %[1]q + arn = aws_sns_topic.test.arn +} + +resource "aws_sns_topic" "test" { + name = %[2]q +} + +resource "aws_cloudwatch_event_rule" "test" { + name = %[3]q + event_bus_name = aws_cloudwatch_event_bus.test.name + event_pattern = < Date: Wed, 28 Jul 2021 13:03:43 +0100 Subject: [PATCH 09/26] Fix EventBusArn event bus target test. --- ...resource_aws_cloudwatch_event_target_test.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index 79714f1b0d24..e3ac9aca3983 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -227,7 +227,6 @@ func TestAccAWSCloudWatchEventTarget_EventBusArn(t *testing.T) { if err != nil { t.Skipf("Environment variable %s is missing or is not a valid ARN", key) } - busName := strings.Replace(busArn.Resource, "event-bus/", "", 1) var target events.Target ruleName := acctest.RandomWithPrefix("tf-acc-test-rule") @@ -241,11 +240,11 @@ func TestAccAWSCloudWatchEventTarget_EventBusArn(t *testing.T) { CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudWatchEventTargetConfigEventBusName(ruleName, busName, snsTopicName, targetID), + Config: testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, busArn.String(), snsTopicName, targetID), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventTargetExists(resourceName, &target), resource.TestCheckResourceAttr(resourceName, "rule", ruleName), - resource.TestCheckResourceAttr(resourceName, "event_bus_name", busName), + resource.TestCheckResourceAttr(resourceName, "event_bus_name", busArn.String()), resource.TestCheckResourceAttr(resourceName, "target_id", targetID), ), }, @@ -985,11 +984,11 @@ resource "aws_cloudwatch_event_bus" "test" { `, targetID, snsTopicName, ruleName, eventBusName) } -func testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, eventBusName, snsTopicName, targetID string) string { +func testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, eventBusArn, snsTopicName, targetID string) string { return fmt.Sprintf(` resource "aws_cloudwatch_event_target" "test" { rule = aws_cloudwatch_event_rule.test.name - event_bus_name = aws_cloudwatch_event_rule.test.event_bus_name + event_bus_name = %[4]q target_id = %[1]q arn = aws_sns_topic.test.arn } @@ -1000,7 +999,7 @@ resource "aws_sns_topic" "test" { resource "aws_cloudwatch_event_rule" "test" { name = %[3]q - event_bus_name = aws_cloudwatch_event_bus.test.name + event_bus_name = %[4]q event_pattern = < Date: Thu, 29 Jul 2021 11:40:27 +0100 Subject: [PATCH 10/26] Revert "Delete dependabot.yml" This reverts commit d3fe8498ec2ab817ec1c599e1f709079d4ccc564. --- .github/dependabot.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000000..9d24fb90511d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,31 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: "gomod" + directory: "/" + ignore: + - dependency-name: "golang.org/x/tools" + - dependency-name: "google.golang.org/grpc" + schedule: + interval: "daily" + - package-ecosystem: "gomod" + directory: "/awsproviderlint" + ignore: + - dependency-name: "golang.org/x/tools" + - dependency-name: "google.golang.org/grpc" + schedule: + interval: "daily" + - package-ecosystem: "gomod" + directory: "/tools" + ignore: + - dependency-name: "golang.org/x/tools" + - dependency-name: "google.golang.org/grpc" + schedule: + interval: "daily" + - package-ecosystem: "terraform" + directory: "/infrastructure/repository" + schedule: + interval: "daily" From f80e5f1d26abae955d97b02655480452202fc4df Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Thu, 29 Jul 2021 11:52:53 +0100 Subject: [PATCH 11/26] Add new TF configuration for event bus rule with arn test. --- aws/resource_aws_cloudwatch_event_rule_test.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index 9b092809e77f..7948ad9f0633 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -552,7 +552,7 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudWatchEventRulePartnerEventBusConfig(rName, busArn.String()), + Config: testAccAWSCloudWatchEventRulePartnerEventBusArn(rName, busArn.String()), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventRuleExists(resourceName, &v), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s$`, busName, rName))), @@ -843,3 +843,18 @@ PATTERN } `, rName, eventBusName) } + +func testAccAWSCloudWatchEventRulePartnerEventBusArn(rName, eventBusName string) string { + return fmt.Sprintf(` +resource "aws_cloudwatch_event_rule" "test" { + name = %[1]q + event_bus_name = %[2]q + + event_pattern = < Date: Thu, 29 Jul 2021 15:58:14 +0100 Subject: [PATCH 12/26] Fix typo on event rule test. --- aws/resource_aws_cloudwatch_event_rule_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index 7948ad9f0633..e318019affeb 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -555,7 +555,7 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { Config: testAccAWSCloudWatchEventRulePartnerEventBusArn(rName, busArn.String()), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventRuleExists(resourceName, &v), - testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s$`, busName, rName))), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s`, busName, rName))), resource.TestCheckResourceAttr(resourceName, "description", ""), resource.TestCheckResourceAttr(resourceName, "event_bus_name", busArn.String()), testAccCheckResourceAttrEquivalentJSON(resourceName, "event_pattern", "{\"source\":[\"aws.ec2\"]}"), From 1a2803d89b59e43f6c3cc58e1cea05945bbc46c7 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Thu, 29 Jul 2021 17:10:45 +0100 Subject: [PATCH 13/26] Remove event bus rule dependency on AWS_DEFAULT_REGION env var. --- ...resource_aws_cloudwatch_event_rule_test.go | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index e318019affeb..92ff60d5b4fd 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -555,7 +555,7 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { Config: testAccAWSCloudWatchEventRulePartnerEventBusArn(rName, busArn.String()), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventRuleExists(resourceName, &v), - testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s`, busName, rName))), + testAccCheckRuleARN(resourceName, "arn", fmt.Sprintf(`rule/%s/%s`, busName, rName), "events", busArn), resource.TestCheckResourceAttr(resourceName, "description", ""), resource.TestCheckResourceAttr(resourceName, "event_bus_name", busArn.String()), testAccCheckResourceAttrEquivalentJSON(resourceName, "event_pattern", "{\"source\":[\"aws.ec2\"]}"), @@ -665,6 +665,26 @@ func testAccAWSCloudWatchEventRuleNoBusNameImportStateIdFunc(resourceName string } } +func testAccCheckRuleARN(resourceName, attributeName, arnResource, arnService string, eventBusARN awsarn.ARN) resource.TestCheckFunc { + return func(s *terraform.State) error { + arnRegexp := awsarn.ARN{ + AccountID: eventBusARN.AccountID, + Partition: eventBusARN.Partition, + Region: eventBusARN.Region, + Resource: arnResource, + Service: arnService, + }.String() + + attributeMatch, err := regexp.Compile(arnRegexp) + + if err != nil { + return fmt.Errorf("Unable to compile ARN regexp (%s): %w", arnRegexp, err) + } + + return resource.TestMatchResourceAttr(resourceName, attributeName, attributeMatch)(s) + } +} + func testAccAWSCloudWatchEventRuleConfig(name string) string { return fmt.Sprintf(` resource "aws_cloudwatch_event_rule" "test" { From 9c61947b431d66e7b28e6c62003d3809e0b45ffb Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Fri, 30 Jul 2021 15:51:00 +0100 Subject: [PATCH 14/26] Fix event target test. --- ...source_aws_cloudwatch_event_target_test.go | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index e3ac9aca3983..1c55b3f0c26a 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - awsarn "github.com/aws/aws-sdk-go/aws/arn" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -222,16 +221,12 @@ func TestAccAWSCloudWatchEventTarget_EventBusName(t *testing.T) { func TestAccAWSCloudWatchEventTarget_EventBusArn(t *testing.T) { resourceName := "aws_cloudwatch_event_target.test" - key := "EVENT_BRIDGE_EVENT_BUS_ARN" - busArn, err := awsarn.Parse(os.Getenv(key)) - if err != nil { - t.Skipf("Environment variable %s is missing or is not a valid ARN", key) - } var target events.Target ruleName := acctest.RandomWithPrefix("tf-acc-test-rule") - snsTopicName := acctest.RandomWithPrefix("tf-acc-test-sns") targetID := acctest.RandomWithPrefix("tf-acc-test-target") + originEventBusName := acctest.RandomWithPrefix("tf-acc-test") + targetEventBusName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -240,11 +235,12 @@ func TestAccAWSCloudWatchEventTarget_EventBusArn(t *testing.T) { CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, busArn.String(), snsTopicName, targetID), + Config: testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, originEventBusName, targetID, targetEventBusName, acctest.RandomWithPrefix("tf-acc-test-target"), acctest.RandomWithPrefix("tf-acc-test-target")), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventTargetExists(resourceName, &target), resource.TestCheckResourceAttr(resourceName, "rule", ruleName), - resource.TestCheckResourceAttr(resourceName, "event_bus_name", busArn.String()), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf("event-bus/%s", targetEventBusName))), + testAccMatchResourceAttrRegionalARN(resourceName, "event_bus_name", "events", regexp.MustCompile(fmt.Sprintf("event-bus/%s", originEventBusName))), resource.TestCheckResourceAttr(resourceName, "target_id", targetID), ), }, @@ -984,23 +980,30 @@ resource "aws_cloudwatch_event_bus" "test" { `, targetID, snsTopicName, ruleName, eventBusName) } -func testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, eventBusArn, snsTopicName, targetID string) string { +func testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, originEventBusName, targetID, targetEventBusName, roleName, policyName string) string { return fmt.Sprintf(` -resource "aws_cloudwatch_event_target" "test" { - rule = aws_cloudwatch_event_rule.test.name - event_bus_name = %[4]q - target_id = %[1]q - arn = aws_sns_topic.test.arn +data "aws_partition" "current" {} + +resource "aws_cloudwatch_event_bus" "test_origin_bus" { + name = %[1]q } -resource "aws_sns_topic" "test" { - name = %[2]q +resource "aws_cloudwatch_event_bus" "test_destination_bus" { + name = %[4]q +} + +resource "aws_cloudwatch_event_target" "test" { + rule = aws_cloudwatch_event_rule.test.name + event_bus_name = aws_cloudwatch_event_bus.test_origin_bus.arn + target_id = %[3]q + arn = aws_cloudwatch_event_bus.test_destination_bus.arn + role_arn = aws_iam_role.test.arn } resource "aws_cloudwatch_event_rule" "test" { - name = %[3]q - event_bus_name = %[4]q - event_pattern = < Date: Mon, 2 Aug 2021 16:15:24 +0100 Subject: [PATCH 15/26] Remove reliance on EVENT_BRIDGE_EVENT_BUS_ARN env var. --- ...resource_aws_cloudwatch_event_rule_test.go | 23 ++++++++----------- docs/MAINTAINING.md | 1 - 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index 92ff60d5b4fd..97f548a6e037 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -5,7 +5,6 @@ import ( "log" "os" "regexp" - "strings" "testing" "github.com/aws/aws-sdk-go/aws" @@ -534,16 +533,10 @@ func TestAccAWSCloudWatchEventRule_PartnerEventBus(t *testing.T) { } func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { - key := "EVENT_BRIDGE_EVENT_BUS_ARN" - busArn, err := awsarn.Parse(os.Getenv(key)) - if err != nil { - t.Skipf("Environment variable %s is missing or is not a valid ARN", key) - } - busName := strings.Replace(busArn.Resource, "event-bus/", "", 1) - var v events.DescribeRuleOutput rName := acctest.RandomWithPrefix("tf-acc-test-rule") resourceName := "aws_cloudwatch_event_rule.test" + eventBusName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -552,12 +545,12 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudWatchEventRulePartnerEventBusArn(rName, busArn.String()), + Config: testAccAWSCloudWatchEventRuleEventBusArn(rName, eventBusName), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventRuleExists(resourceName, &v), - testAccCheckRuleARN(resourceName, "arn", fmt.Sprintf(`rule/%s/%s`, busName, rName), "events", busArn), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s$`, eventBusName, rName))), resource.TestCheckResourceAttr(resourceName, "description", ""), - resource.TestCheckResourceAttr(resourceName, "event_bus_name", busArn.String()), + resource.TestCheckResourceAttrPair(resourceName, "event_bus_name", "aws_cloudwatch_event_bus.test", "arn"), testAccCheckResourceAttrEquivalentJSON(resourceName, "event_pattern", "{\"source\":[\"aws.ec2\"]}"), resource.TestCheckResourceAttr(resourceName, "is_enabled", "true"), resource.TestCheckResourceAttr(resourceName, "name", rName), @@ -864,11 +857,15 @@ PATTERN `, rName, eventBusName) } -func testAccAWSCloudWatchEventRulePartnerEventBusArn(rName, eventBusName string) string { +func testAccAWSCloudWatchEventRuleEventBusArn(rName, eventBusName string) string { return fmt.Sprintf(` +resource "aws_cloudwatch_event_bus" "test" { + name = %[2]q +} + resource "aws_cloudwatch_event_rule" "test" { name = %[1]q - event_bus_name = %[2]q + event_bus_name = aws_cloudwatch_event_bus.test.arn event_pattern = < Date: Tue, 3 Aug 2021 11:08:25 +0100 Subject: [PATCH 16/26] Remove unused function. --- ...resource_aws_cloudwatch_event_rule_test.go | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index 97f548a6e037..dc31668f5fd5 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - awsarn "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/cloudwatchevents" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/go-multierror" @@ -658,26 +657,6 @@ func testAccAWSCloudWatchEventRuleNoBusNameImportStateIdFunc(resourceName string } } -func testAccCheckRuleARN(resourceName, attributeName, arnResource, arnService string, eventBusARN awsarn.ARN) resource.TestCheckFunc { - return func(s *terraform.State) error { - arnRegexp := awsarn.ARN{ - AccountID: eventBusARN.AccountID, - Partition: eventBusARN.Partition, - Region: eventBusARN.Region, - Resource: arnResource, - Service: arnService, - }.String() - - attributeMatch, err := regexp.Compile(arnRegexp) - - if err != nil { - return fmt.Errorf("Unable to compile ARN regexp (%s): %w", arnRegexp, err) - } - - return resource.TestMatchResourceAttr(resourceName, attributeName, attributeMatch)(s) - } -} - func testAccAWSCloudWatchEventRuleConfig(name string) string { return fmt.Sprintf(` resource "aws_cloudwatch_event_rule" "test" { From 1d5487d45eebbc912a0d74df201252d866db19c7 Mon Sep 17 00:00:00 2001 From: FrancescoFucile-CAZ Date: Wed, 4 Aug 2021 11:45:05 +0100 Subject: [PATCH 17/26] Rename parameters for test function for clarity. --- aws/resource_aws_cloudwatch_event_target_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index 1c55b3f0c26a..a19e8169afae 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -226,7 +226,7 @@ func TestAccAWSCloudWatchEventTarget_EventBusArn(t *testing.T) { ruleName := acctest.RandomWithPrefix("tf-acc-test-rule") targetID := acctest.RandomWithPrefix("tf-acc-test-target") originEventBusName := acctest.RandomWithPrefix("tf-acc-test") - targetEventBusName := acctest.RandomWithPrefix("tf-acc-test") + destinationEventBusName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -235,11 +235,11 @@ func TestAccAWSCloudWatchEventTarget_EventBusArn(t *testing.T) { CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, originEventBusName, targetID, targetEventBusName, acctest.RandomWithPrefix("tf-acc-test-target"), acctest.RandomWithPrefix("tf-acc-test-target")), + Config: testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, originEventBusName, targetID, destinationEventBusName, acctest.RandomWithPrefix("tf-acc-test-target"), acctest.RandomWithPrefix("tf-acc-test-target")), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventTargetExists(resourceName, &target), resource.TestCheckResourceAttr(resourceName, "rule", ruleName), - testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf("event-bus/%s", targetEventBusName))), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf("event-bus/%s", destinationEventBusName))), testAccMatchResourceAttrRegionalARN(resourceName, "event_bus_name", "events", regexp.MustCompile(fmt.Sprintf("event-bus/%s", originEventBusName))), resource.TestCheckResourceAttr(resourceName, "target_id", targetID), ), @@ -980,7 +980,7 @@ resource "aws_cloudwatch_event_bus" "test" { `, targetID, snsTopicName, ruleName, eventBusName) } -func testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, originEventBusName, targetID, targetEventBusName, roleName, policyName string) string { +func testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, originEventBusName, targetID, destinationEventBusName, roleName, policyName string) string { return fmt.Sprintf(` data "aws_partition" "current" {} @@ -1030,7 +1030,7 @@ resource "aws_iam_role" "test" { } EOF } -`, originEventBusName, ruleName, targetID, targetEventBusName, roleName, policyName) +`, originEventBusName, ruleName, targetID, destinationEventBusName, roleName, policyName) } func testAccAWSCloudWatchEventTargetConfigMissingTargetId(ruleName, snsTopicName string) string { From a0e8d699d4914662a5b289c9ba77a9baba61f32c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 18 Aug 2021 10:10:18 -0400 Subject: [PATCH 18/26] Add CHANGELOG entry. --- .changelog/20312.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/20312.txt diff --git a/.changelog/20312.txt b/.changelog/20312.txt new file mode 100644 index 000000000000..32e20365f6de --- /dev/null +++ b/.changelog/20312.txt @@ -0,0 +1,7 @@ +```release-note:bug +aws/resource_aws_cloudwatch_event_rule: Correctly handle ARN in `event_bus_name` argument +``` + +```release-note:bug +aws/resource_aws_cloudwatch_event_target: Correctly handle ARN in `event_bus_name` argument +``` \ No newline at end of file From 1770fa31da16be0e17b0cb502d572d41911b4f3c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 18 Aug 2021 10:55:54 -0400 Subject: [PATCH 19/26] Rename CloudWatch Events resource ID functions. --- aws/internal/service/cloudwatchevents/enum.go | 5 ++ .../service/cloudwatchevents/finder/finder.go | 15 +---- aws/internal/service/cloudwatchevents/id.go | 67 +++++++++++-------- .../service/cloudwatchevents/id_test.go | 12 ++-- ...esource_aws_cloudwatch_event_permission.go | 8 +-- ...ce_aws_cloudwatch_event_permission_test.go | 4 +- aws/resource_aws_cloudwatch_event_rule.go | 6 +- aws/resource_aws_cloudwatch_event_target.go | 6 +- 8 files changed, 65 insertions(+), 58 deletions(-) create mode 100644 aws/internal/service/cloudwatchevents/enum.go diff --git a/aws/internal/service/cloudwatchevents/enum.go b/aws/internal/service/cloudwatchevents/enum.go new file mode 100644 index 000000000000..a4ed557c839b --- /dev/null +++ b/aws/internal/service/cloudwatchevents/enum.go @@ -0,0 +1,5 @@ +package cloudwatchevents + +const ( + DefaultEventBusName = "default" +) diff --git a/aws/internal/service/cloudwatchevents/finder/finder.go b/aws/internal/service/cloudwatchevents/finder/finder.go index c270732ddb0e..fb91979505ff 100644 --- a/aws/internal/service/cloudwatchevents/finder/finder.go +++ b/aws/internal/service/cloudwatchevents/finder/finder.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/aws/aws-sdk-go/aws" - awsarn "github.com/aws/aws-sdk-go/aws/arn" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -48,21 +47,11 @@ func Rule(conn *events.CloudWatchEvents, eventBusName, ruleName string) (*events input.EventBusName = aws.String(eventBusName) } - out, err := conn.DescribeRule(&input) - - if err == nil && awsarn.IsARN(eventBusName) { - eventBusArn, _ := awsarn.Parse(eventBusName) - eventBusArn.Resource = "event-bus/" + *out.EventBusName - updatedEventBusArn := eventBusArn.String() - out.EventBusName = &updatedEventBusArn - } - - return out, err - + return conn.DescribeRule(&input) } func RuleByID(conn *events.CloudWatchEvents, ruleID string) (*events.DescribeRuleOutput, error) { - busName, ruleName, err := tfevents.RuleParseID(ruleID) + busName, ruleName, err := tfevents.RuleParseResourceID(ruleID) if err != nil { return nil, err } diff --git a/aws/internal/service/cloudwatchevents/id.go b/aws/internal/service/cloudwatchevents/id.go index 5a9d8b2bc723..7072ad0dc5aa 100644 --- a/aws/internal/service/cloudwatchevents/id.go +++ b/aws/internal/service/cloudwatchevents/id.go @@ -4,27 +4,29 @@ import ( "fmt" "regexp" "strings" - - awsarn "github.com/aws/aws-sdk-go/aws/arn" ) var ( + eventBusNamePattern = regexp.MustCompile(`(arn:aws[\w-]*:events:[a-z]{2}-[a-z]+-[\w-]+:[0-9]{12}:event-bus\/)?[/\.\-_A-Za-z0-9]+`) partnerEventBusPattern = regexp.MustCompile(`^aws\.partner(/[\.\-_A-Za-z0-9]+){2,}$`) ) -const DefaultEventBusName = "default" - -const PermissionIDSeparator = "/" +const permissionResourceIDSeparator = "/" -func PermissionCreateID(eventBusName, statementID string) string { +func PermissionCreateResourceID(eventBusName, statementID string) string { if eventBusName == "" || eventBusName == DefaultEventBusName { return statementID } - return eventBusName + PermissionIDSeparator + statementID + + parts := []string{eventBusName, statementID} + id := strings.Join(parts, permissionResourceIDSeparator) + + return id } -func PermissionParseID(id string) (string, string, error) { - parts := strings.Split(id, PermissionIDSeparator) +func PermissionParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, permissionResourceIDSeparator) + if len(parts) == 1 && parts[0] != "" { return DefaultEventBusName, parts[0], nil } @@ -32,20 +34,25 @@ func PermissionParseID(id string) (string, string, error) { return parts[0], parts[1], nil } - return "", "", fmt.Errorf("unexpected format for ID (%q), expected "+PermissionIDSeparator+" or ", id) + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sSTATEMENTID or STATEMENTID", id, permissionResourceIDSeparator) } -const ruleIDSeparator = "/" +const ruleResourceIDSeparator = "/" -func RuleCreateID(eventBusName, ruleName string) string { +func RuleCreateResourceID(eventBusName, ruleName string) string { if eventBusName == "" || eventBusName == DefaultEventBusName { return ruleName } - return eventBusName + ruleIDSeparator + ruleName + + parts := []string{eventBusName, ruleName} + id := strings.Join(parts, ruleResourceIDSeparator) + + return id } -func RuleParseID(id string) (string, string, error) { - parts := strings.Split(id, ruleIDSeparator) +func RuleParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, ruleResourceIDSeparator) + if len(parts) == 1 && parts[0] != "" { return DefaultEventBusName, parts[0], nil } @@ -53,33 +60,39 @@ func RuleParseID(id string) (string, string, error) { return parts[0], parts[1], nil } if len(parts) > 2 { - i := strings.LastIndex(id, ruleIDSeparator) + i := strings.LastIndex(id, ruleResourceIDSeparator) busName := id[:i] statementID := id[i+1:] - if (partnerEventBusPattern.MatchString(busName) || awsarn.IsARN(busName)) && statementID != "" { + if partnerEventBusPattern.MatchString(busName) && statementID != "" { return busName, statementID, nil } } - return "", "", fmt.Errorf("unexpected format for ID (%q), expected "+ruleIDSeparator+" or ", id) + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sRULENAME or RULENAME", id, ruleResourceIDSeparator) } -// Terraform state IDs for Targets are not parseable, since the separator used ("-") is also a valid -// character in both the rule name and the target id. +// Terraform resource IDs for Targets are not parseable as the separator used ("-") is also a valid character in both the rule name and the target ID. -const targetIDSeparator = "-" +const targetResourceIDSeparator = "-" const targetImportIDSeparator = "/" -func TargetCreateID(eventBusName, ruleName, targetID string) string { - id := ruleName + targetIDSeparator + targetID - if eventBusName != "" && eventBusName != DefaultEventBusName { - id = eventBusName + targetIDSeparator + id +func TargetCreateResourceID(eventBusName, ruleName, targetID string) string { + var parts []string + + if eventBusName == "" || eventBusName == DefaultEventBusName { + parts = []string{ruleName, targetID} + } else { + parts = []string{eventBusName, ruleName, targetID} } + + id := strings.Join(parts, targetResourceIDSeparator) + return id } func TargetParseImportID(id string) (string, string, string, error) { parts := strings.Split(id, targetImportIDSeparator) + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { return DefaultEventBusName, parts[0], parts[1], nil } @@ -92,10 +105,10 @@ func TargetParseImportID(id string) (string, string, string, error) { iRule := strings.LastIndex(id[:iTarget], targetImportIDSeparator) busName := id[:iRule] ruleName := id[iRule+1 : iTarget] - if (partnerEventBusPattern.MatchString(busName) || awsarn.IsARN(busName)) && ruleName != "" && targetID != "" { + if partnerEventBusPattern.MatchString(busName) && ruleName != "" && targetID != "" { return busName, ruleName, targetID, nil } } - return "", "", "", fmt.Errorf("unexpected format for ID (%q), expected "+targetImportIDSeparator+""+targetImportIDSeparator+" or "+targetImportIDSeparator+"", id) + return "", "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sRULENAME%[2]sTARGETID or RULENAME%[2]sTARGETID", id, targetImportIDSeparator) } diff --git a/aws/internal/service/cloudwatchevents/id_test.go b/aws/internal/service/cloudwatchevents/id_test.go index 97ae7823a903..eae8f094d1d0 100644 --- a/aws/internal/service/cloudwatchevents/id_test.go +++ b/aws/internal/service/cloudwatchevents/id_test.go @@ -27,13 +27,13 @@ func TestPermissionParseID(t *testing.T) { }, { TestName: "two parts", - InputID: tfevents.PermissionCreateID("TestEventBus", "TestStatement"), + InputID: tfevents.PermissionCreateResourceID("TestEventBus", "TestStatement"), ExpectedPart0: "TestEventBus", ExpectedPart1: "TestStatement", }, { TestName: "two parts with default event bus", - InputID: tfevents.PermissionCreateID(tfevents.DefaultEventBusName, "TestStatement"), + InputID: tfevents.PermissionCreateResourceID(tfevents.DefaultEventBusName, "TestStatement"), ExpectedPart0: tfevents.DefaultEventBusName, ExpectedPart1: "TestStatement", }, @@ -66,7 +66,7 @@ func TestPermissionParseID(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.TestName, func(t *testing.T) { - gotPart0, gotPart1, err := tfevents.PermissionParseID(testCase.InputID) + gotPart0, gotPart1, err := tfevents.PermissionParseResourceID(testCase.InputID) if err == nil && testCase.ExpectedError { t.Fatalf("expected error, got no error") @@ -108,13 +108,13 @@ func TestRuleParseID(t *testing.T) { }, { TestName: "two parts", - InputID: tfevents.RuleCreateID("TestEventBus", "TestRule"), + InputID: tfevents.RuleCreateResourceID("TestEventBus", "TestRule"), ExpectedPart0: "TestEventBus", ExpectedPart1: "TestRule", }, { TestName: "two parts with default event bus", - InputID: tfevents.RuleCreateID(tfevents.DefaultEventBusName, "TestRule"), + InputID: tfevents.RuleCreateResourceID(tfevents.DefaultEventBusName, "TestRule"), ExpectedPart0: tfevents.DefaultEventBusName, ExpectedPart1: "TestRule", }, @@ -163,7 +163,7 @@ func TestRuleParseID(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.TestName, func(t *testing.T) { - gotPart0, gotPart1, err := tfevents.RuleParseID(testCase.InputID) + gotPart0, gotPart1, err := tfevents.RuleParseResourceID(testCase.InputID) if err == nil && testCase.ExpectedError { t.Fatalf("expected error, got no error") diff --git a/aws/resource_aws_cloudwatch_event_permission.go b/aws/resource_aws_cloudwatch_event_permission.go index d97cdd5769e1..d3c7fdfef65a 100644 --- a/aws/resource_aws_cloudwatch_event_permission.go +++ b/aws/resource_aws_cloudwatch_event_permission.go @@ -100,7 +100,7 @@ func resourceAwsCloudWatchEventPermissionCreate(d *schema.ResourceData, meta int return fmt.Errorf("Creating CloudWatch Events permission failed: %w", err) } - id := tfevents.PermissionCreateID(eventBusName, statementID) + id := tfevents.PermissionCreateResourceID(eventBusName, statementID) d.SetId(id) return resourceAwsCloudWatchEventPermissionRead(d, meta) @@ -110,7 +110,7 @@ func resourceAwsCloudWatchEventPermissionCreate(d *schema.ResourceData, meta int func resourceAwsCloudWatchEventPermissionRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - eventBusName, statementID, err := tfevents.PermissionParseID(d.Id()) + eventBusName, statementID, err := tfevents.PermissionParseResourceID(d.Id()) if err != nil { return fmt.Errorf("error reading CloudWatch Events permission (%s): %w", d.Id(), err) } @@ -207,7 +207,7 @@ func getPolicyStatement(output *events.DescribeEventBusOutput, statementID strin func resourceAwsCloudWatchEventPermissionUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - eventBusName, statementID, err := tfevents.PermissionParseID(d.Id()) + eventBusName, statementID, err := tfevents.PermissionParseResourceID(d.Id()) if err != nil { return fmt.Errorf("error updating CloudWatch Events permission (%s): %w", d.Id(), err) } @@ -236,7 +236,7 @@ func resourceAwsCloudWatchEventPermissionUpdate(d *schema.ResourceData, meta int func resourceAwsCloudWatchEventPermissionDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - eventBusName, statementID, err := tfevents.PermissionParseID(d.Id()) + eventBusName, statementID, err := tfevents.PermissionParseResourceID(d.Id()) if err != nil { return fmt.Errorf("error deleting CloudWatch Events permission (%s): %w", d.Id(), err) } diff --git a/aws/resource_aws_cloudwatch_event_permission_test.go b/aws/resource_aws_cloudwatch_event_permission_test.go index 153309ab0383..1a66758e3400 100644 --- a/aws/resource_aws_cloudwatch_event_permission_test.go +++ b/aws/resource_aws_cloudwatch_event_permission_test.go @@ -326,7 +326,7 @@ func testAccCheckCloudWatchEventPermissionExists(pr string) resource.TestCheckFu return fmt.Errorf("No ID is set") } - eventBusName, statementID, err := tfevents.PermissionParseID(rs.Primary.ID) + eventBusName, statementID, err := tfevents.PermissionParseResourceID(rs.Primary.ID) if err != nil { return fmt.Errorf("error reading CloudWatch Events permission (%s): %w", pr, err) } @@ -361,7 +361,7 @@ func testAccCheckCloudWatchEventPermissionDestroy(s *terraform.State) error { continue } - eventBusName, statementID, err := tfevents.PermissionParseID(rs.Primary.ID) + eventBusName, statementID, err := tfevents.PermissionParseResourceID(rs.Primary.ID) if err != nil { return fmt.Errorf("error reading CloudWatch Events permission (%s): %w", rs.Primary.ID, err) } diff --git a/aws/resource_aws_cloudwatch_event_rule.go b/aws/resource_aws_cloudwatch_event_rule.go index a3c3f2d263bf..95261f6d9cda 100644 --- a/aws/resource_aws_cloudwatch_event_rule.go +++ b/aws/resource_aws_cloudwatch_event_rule.go @@ -142,7 +142,7 @@ func resourceAwsCloudWatchEventRuleCreate(d *schema.ResourceData, meta interface d.Set("arn", out.RuleArn) - id := tfevents.RuleCreateID(aws.StringValue(input.EventBusName), aws.StringValue(input.Name)) + id := tfevents.RuleCreateResourceID(aws.StringValue(input.EventBusName), aws.StringValue(input.Name)) d.SetId(id) log.Printf("[INFO] CloudWatch Events Rule (%s) created", aws.StringValue(out.RuleArn)) @@ -211,7 +211,7 @@ func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{} func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - _, ruleName, err := tfevents.RuleParseID(d.Id()) + _, ruleName, err := tfevents.RuleParseResourceID(d.Id()) if err != nil { return err } @@ -256,7 +256,7 @@ func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface func resourceAwsCloudWatchEventRuleDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - busName, ruleName, err := tfevents.RuleParseID(d.Id()) + busName, ruleName, err := tfevents.RuleParseResourceID(d.Id()) if err != nil { return err } diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index 8b0a2c4e5619..023041718a3e 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -50,7 +50,7 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: validateCloudWatchEventBusNameOrARN, + ValidateFunc: validateCloudWatchEventRuleName, }, "target_id": { @@ -413,7 +413,7 @@ func resourceAwsCloudWatchEventTargetCreate(d *schema.ResourceData, meta interfa return fmt.Errorf("Creating CloudWatch Events Target failed: %s", out.FailedEntries) } - id := tfevents.TargetCreateID(busName, rule, targetID) + id := tfevents.TargetCreateResourceID(busName, rule, targetID) d.SetId(id) log.Printf("[INFO] CloudWatch Events Target (%s) created", d.Id()) @@ -1064,7 +1064,7 @@ func resourceAwsCloudWatchEventTargetImport(d *schema.ResourceData, meta interfa return []*schema.ResourceData{}, err } - id := tfevents.TargetCreateID(busName, ruleName, targetID) + id := tfevents.TargetCreateResourceID(busName, ruleName, targetID) d.SetId(id) d.Set("target_id", targetID) d.Set("rule", ruleName) From aba89ae74512850dcdd0b3c204e5c1c03432d20f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 18 Aug 2021 11:41:07 -0400 Subject: [PATCH 20/26] Support event bus ARN when parsing Rule resource ID and Target import ID. --- aws/internal/service/cloudwatchevents/id.go | 22 ++++++++++++------- .../service/cloudwatchevents/id_test.go | 21 +++++++++++++++++- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/aws/internal/service/cloudwatchevents/id.go b/aws/internal/service/cloudwatchevents/id.go index 7072ad0dc5aa..34a73a59a703 100644 --- a/aws/internal/service/cloudwatchevents/id.go +++ b/aws/internal/service/cloudwatchevents/id.go @@ -7,7 +7,7 @@ import ( ) var ( - eventBusNamePattern = regexp.MustCompile(`(arn:aws[\w-]*:events:[a-z]{2}-[a-z]+-[\w-]+:[0-9]{12}:event-bus\/)?[/\.\-_A-Za-z0-9]+`) + eventBusARNPattern = regexp.MustCompile(`^arn:aws[\w-]*:events:[a-z]{2}-[a-z]+-[\w-]+:[0-9]{12}:event-bus\/[\.\-_A-Za-z0-9]+$`) partnerEventBusPattern = regexp.MustCompile(`^aws\.partner(/[\.\-_A-Za-z0-9]+){2,}$`) ) @@ -61,10 +61,13 @@ func RuleParseResourceID(id string) (string, string, error) { } if len(parts) > 2 { i := strings.LastIndex(id, ruleResourceIDSeparator) - busName := id[:i] - statementID := id[i+1:] - if partnerEventBusPattern.MatchString(busName) && statementID != "" { - return busName, statementID, nil + eventBusName := id[:i] + ruleName := id[i+1:] + if eventBusARNPattern.MatchString(eventBusName) && ruleName != "" { + return eventBusName, ruleName, nil + } + if partnerEventBusPattern.MatchString(eventBusName) && ruleName != "" { + return eventBusName, ruleName, nil } } @@ -103,10 +106,13 @@ func TargetParseImportID(id string) (string, string, string, error) { iTarget := strings.LastIndex(id, targetImportIDSeparator) targetID := id[iTarget+1:] iRule := strings.LastIndex(id[:iTarget], targetImportIDSeparator) - busName := id[:iRule] + eventBusName := id[:iRule] ruleName := id[iRule+1 : iTarget] - if partnerEventBusPattern.MatchString(busName) && ruleName != "" && targetID != "" { - return busName, ruleName, targetID, nil + if eventBusARNPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" { + return eventBusName, ruleName, targetID, nil + } + if partnerEventBusPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" { + return eventBusName, ruleName, targetID, nil } } diff --git a/aws/internal/service/cloudwatchevents/id_test.go b/aws/internal/service/cloudwatchevents/id_test.go index eae8f094d1d0..ad36ee5421b7 100644 --- a/aws/internal/service/cloudwatchevents/id_test.go +++ b/aws/internal/service/cloudwatchevents/id_test.go @@ -119,11 +119,23 @@ func TestRuleParseID(t *testing.T) { ExpectedPart1: "TestRule", }, { - TestName: "partner event bus", + TestName: "partner event bus 1", InputID: "aws.partner/example.com/Test/TestRule", ExpectedPart0: "aws.partner/example.com/Test", ExpectedPart1: "TestRule", }, + { + TestName: "partner event bus 2", + InputID: "aws.partner/foo.com/foo/18554d09-58ff-aa42-ba9c-c4c33899006f/test", + ExpectedPart0: "aws.partner/foo.com/foo/18554d09-58ff-aa42-ba9c-c4c33899006f", + ExpectedPart1: "test", + }, + { + TestName: "ARN event bus", + InputID: tfevents.RuleCreateResourceID("arn:aws:events:us-east-2:123456789012:event-bus/default", "TestRule"), + ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/default", + ExpectedPart1: "TestRule", + }, { TestName: "empty both parts", InputID: "/", @@ -281,6 +293,13 @@ func TestTargetParseImportID(t *testing.T) { ExpectedPart1: "TestRule", ExpectedPart2: "TestTarget", }, + { + TestName: "ARN event bus", + InputID: "arn:aws:events:us-east-2:123456789012:event-bus/default/TestRule/TestTarget", + ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/default", + ExpectedPart1: "TestRule", + ExpectedPart2: "TestTarget", + }, { TestName: "empty partner event rule and target", InputID: "aws.partner/example.com/Test//", From 9c33e5727fb2e3159dedf2caa09695869d6e14d6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 18 Aug 2021 13:02:35 -0400 Subject: [PATCH 21/26] Consistently use 'events' as an import alias for 'github.com/aws/aws-sdk-go/service/cloudwatchevents'. --- ...ource_aws_cloudwatch_event_archive_test.go | 9 +++---- ...ce_aws_cloudwatch_event_permission_test.go | 13 +++++---- ...resource_aws_cloudwatch_event_rule_test.go | 27 +++++++++---------- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_archive_test.go b/aws/resource_aws_cloudwatch_event_archive_test.go index 214edcfadcd1..43f82a6af656 100644 --- a/aws/resource_aws_cloudwatch_event_archive_test.go +++ b/aws/resource_aws_cloudwatch_event_archive_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/cloudwatchevents" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -78,7 +77,7 @@ func TestAccAWSCloudWatchEventArchive_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventArchiveDestroy, Steps: []resource.TestStep{ @@ -109,7 +108,7 @@ func TestAccAWSCloudWatchEventArchive_update(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventArchiveDestroy, Steps: []resource.TestStep{ @@ -139,7 +138,7 @@ func TestAccAWSCloudWatchEventArchive_disappears(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventArchiveDestroy, Steps: []resource.TestStep{ @@ -211,7 +210,7 @@ func TestAccAWSCloudWatchEventArchive_retentionSetOnCreation(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventArchiveDestroy, Steps: []resource.TestStep{ diff --git a/aws/resource_aws_cloudwatch_event_permission_test.go b/aws/resource_aws_cloudwatch_event_permission_test.go index 1a66758e3400..4d01f5fca7d4 100644 --- a/aws/resource_aws_cloudwatch_event_permission_test.go +++ b/aws/resource_aws_cloudwatch_event_permission_test.go @@ -9,7 +9,6 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/cloudwatchevents" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -76,7 +75,7 @@ func TestAccAWSCloudWatchEventPermission_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckCloudWatchEventPermissionDestroy, Steps: []resource.TestStep{ @@ -148,7 +147,7 @@ func TestAccAWSCloudWatchEventPermission_EventBusName(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckCloudWatchEventPermissionDestroy, Steps: []resource.TestStep{ @@ -179,7 +178,7 @@ func TestAccAWSCloudWatchEventPermission_Action(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckCloudWatchEventPermissionDestroy, Steps: []resource.TestStep{ @@ -221,7 +220,7 @@ func TestAccAWSCloudWatchEventPermission_Condition(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckCloudWatchEventPermissionDestroy, Steps: []resource.TestStep{ @@ -264,7 +263,7 @@ func TestAccAWSCloudWatchEventPermission_Multiple(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckCloudWatchEventPermissionDestroy, Steps: []resource.TestStep{ @@ -298,7 +297,7 @@ func TestAccAWSCloudWatchEventPermission_Disappears(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckCloudWatchEventPermissionDestroy, Steps: []resource.TestStep{ diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index dc31668f5fd5..aaa4a173f09a 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/cloudwatchevents" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -95,7 +94,7 @@ func TestAccAWSCloudWatchEventRule_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -166,7 +165,7 @@ func TestAccAWSCloudWatchEventRule_EventBusName(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -216,7 +215,7 @@ func TestAccAWSCloudWatchEventRule_role(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -244,7 +243,7 @@ func TestAccAWSCloudWatchEventRule_description(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -280,7 +279,7 @@ func TestAccAWSCloudWatchEventRule_pattern(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -317,7 +316,7 @@ func TestAccAWSCloudWatchEventRule_ScheduleAndPattern(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -346,7 +345,7 @@ func TestAccAWSCloudWatchEventRule_NamePrefix(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -373,7 +372,7 @@ func TestAccAWSCloudWatchEventRule_Name_Generated(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -401,7 +400,7 @@ func TestAccAWSCloudWatchEventRule_tags(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -453,7 +452,7 @@ func TestAccAWSCloudWatchEventRule_IsEnabled(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -503,7 +502,7 @@ func TestAccAWSCloudWatchEventRule_PartnerEventBus(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -539,7 +538,7 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, cloudwatchevents.EndpointsID), + ErrorCheck: testAccErrorCheck(t, events.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSCloudWatchEventRuleDestroy, Steps: []resource.TestStep{ @@ -549,7 +548,7 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { testAccCheckCloudWatchEventRuleExists(resourceName, &v), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s$`, eventBusName, rName))), resource.TestCheckResourceAttr(resourceName, "description", ""), - resource.TestCheckResourceAttrPair(resourceName, "event_bus_name", "aws_cloudwatch_event_bus.test", "arn"), + //resource.TestCheckResourceAttrPair(resourceName, "event_bus_name", "aws_cloudwatch_event_bus.test", "arn"), testAccCheckResourceAttrEquivalentJSON(resourceName, "event_pattern", "{\"source\":[\"aws.ec2\"]}"), resource.TestCheckResourceAttr(resourceName, "is_enabled", "true"), resource.TestCheckResourceAttr(resourceName, "name", rName), From 8aa6c44fda19e52da321231458f2a7e81d87cac1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 18 Aug 2021 14:12:29 -0400 Subject: [PATCH 22/26] r/aws_cloudwatch_event_rule: Use event bus name from resource ID as API response may collapse any ARN. --- .../service/cloudwatchevents/finder/finder.go | 32 ++++- .../service/cloudwatchevents/id_test.go | 4 +- .../service/cloudwatchevents/state.go | 31 +++++ .../service/cloudwatchevents/state_test.go | 83 ++++++++++++ aws/resource_aws_cloudwatch_event_rule.go | 127 +++++++++--------- ...resource_aws_cloudwatch_event_rule_test.go | 30 +++-- 6 files changed, 228 insertions(+), 79 deletions(-) create mode 100644 aws/internal/service/cloudwatchevents/state.go create mode 100644 aws/internal/service/cloudwatchevents/state_test.go diff --git a/aws/internal/service/cloudwatchevents/finder/finder.go b/aws/internal/service/cloudwatchevents/finder/finder.go index fb91979505ff..65dcf4459d7d 100644 --- a/aws/internal/service/cloudwatchevents/finder/finder.go +++ b/aws/internal/service/cloudwatchevents/finder/finder.go @@ -39,24 +39,46 @@ func ConnectionByName(conn *events.CloudWatchEvents, name string) (*events.Descr return output, nil } -func Rule(conn *events.CloudWatchEvents, eventBusName, ruleName string) (*events.DescribeRuleOutput, error) { +func RuleByEventBusAndRuleNames(conn *events.CloudWatchEvents, eventBusName, ruleName string) (*events.DescribeRuleOutput, error) { input := events.DescribeRuleInput{ Name: aws.String(ruleName), } + if eventBusName != "" { input.EventBusName = aws.String(eventBusName) } - return conn.DescribeRule(&input) + output, err := conn.DescribeRule(&input) + + if tfawserr.ErrCodeEquals(err, events.ErrCodeResourceNotFoundException) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + if output == nil { + return nil, &resource.NotFoundError{ + Message: "Empty result", + LastRequest: input, + } + } + + return output, nil } -func RuleByID(conn *events.CloudWatchEvents, ruleID string) (*events.DescribeRuleOutput, error) { - busName, ruleName, err := tfevents.RuleParseResourceID(ruleID) +func RuleByResourceID(conn *events.CloudWatchEvents, id string) (*events.DescribeRuleOutput, error) { + eventBusName, ruleName, err := tfevents.RuleParseResourceID(id) + if err != nil { return nil, err } - return Rule(conn, busName, ruleName) + return RuleByEventBusAndRuleNames(conn, eventBusName, ruleName) } func Target(conn *events.CloudWatchEvents, busName, ruleName, targetId string) (*events.Target, error) { diff --git a/aws/internal/service/cloudwatchevents/id_test.go b/aws/internal/service/cloudwatchevents/id_test.go index ad36ee5421b7..95009010463c 100644 --- a/aws/internal/service/cloudwatchevents/id_test.go +++ b/aws/internal/service/cloudwatchevents/id_test.go @@ -6,7 +6,7 @@ import ( tfevents "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/cloudwatchevents" ) -func TestPermissionParseID(t *testing.T) { +func TestPermissionParseResourceID(t *testing.T) { testCases := []struct { TestName string InputID string @@ -87,7 +87,7 @@ func TestPermissionParseID(t *testing.T) { } } -func TestRuleParseID(t *testing.T) { +func TestRuleParseResourceID(t *testing.T) { testCases := []struct { TestName string InputID string diff --git a/aws/internal/service/cloudwatchevents/state.go b/aws/internal/service/cloudwatchevents/state.go new file mode 100644 index 000000000000..915ff9618b91 --- /dev/null +++ b/aws/internal/service/cloudwatchevents/state.go @@ -0,0 +1,31 @@ +package cloudwatchevents + +import ( + "fmt" + + events "github.com/aws/aws-sdk-go/service/cloudwatchevents" +) + +// RuleEnabledFromState infers from its state whether or not a rule is enabled. +func RuleEnabledFromState(state string) (bool, error) { + if state == events.RuleStateEnabled { + return true, nil + } + + if state == events.RuleStateDisabled { + return false, nil + } + + // We don't just blindly trust AWS as they tend to return + // unexpected values in similar cases (different casing etc.) + return false, fmt.Errorf("unable to infer enabled from state: %s", state) +} + +// RuleStateFromEnabled returns a rule's state based on whether or not it is enabled. +func RuleStateFromEnabled(enabled bool) string { + if enabled { + return events.RuleStateEnabled + } + + return events.RuleStateDisabled +} diff --git a/aws/internal/service/cloudwatchevents/state_test.go b/aws/internal/service/cloudwatchevents/state_test.go new file mode 100644 index 000000000000..966c95cca806 --- /dev/null +++ b/aws/internal/service/cloudwatchevents/state_test.go @@ -0,0 +1,83 @@ +package cloudwatchevents_test + +import ( + "testing" + + tfevents "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/cloudwatchevents" +) + +func TestRuleEnabledFromState(t *testing.T) { + testCases := []struct { + TestName string + State string + ExpectedError bool + ExpectedEnabled bool + }{ + { + TestName: "empty state", + ExpectedError: true, + }, + { + TestName: "invalid state", + State: "UNKNOWN", + ExpectedError: true, + }, + { + TestName: "enabled", + State: "ENABLED", + ExpectedEnabled: true, + }, + { + TestName: "disabled", + State: "DISABLED", + ExpectedEnabled: false, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.TestName, func(t *testing.T) { + gotEnabled, err := tfevents.RuleEnabledFromState(testCase.State) + + if err == nil && testCase.ExpectedError { + t.Fatalf("expected error, got no error") + } + + if err != nil && !testCase.ExpectedError { + t.Fatalf("got unexpected error: %s", err) + } + + if gotEnabled != testCase.ExpectedEnabled { + t.Errorf("got enabled %t, expected %t", gotEnabled, testCase.ExpectedEnabled) + } + }) + } +} + +func RuleStateFromEnabled(t *testing.T) { + testCases := []struct { + TestName string + Enabled bool + ExpectedState string + }{ + { + TestName: "enabled", + Enabled: true, + ExpectedState: "ENABLED", + }, + { + TestName: "disabled", + Enabled: false, + ExpectedState: "DISABLED", + }, + } + + for _, testCase := range testCases { + t.Run(testCase.TestName, func(t *testing.T) { + gotState := tfevents.RuleStateFromEnabled(testCase.Enabled) + + if gotState != testCase.ExpectedState { + t.Errorf("got enabled %s, expected %s", gotState, testCase.ExpectedState) + } + }) + } +} diff --git a/aws/resource_aws_cloudwatch_event_rule.go b/aws/resource_aws_cloudwatch_event_rule.go index 95261f6d9cda..d37717782db5 100644 --- a/aws/resource_aws_cloudwatch_event_rule.go +++ b/aws/resource_aws_cloudwatch_event_rule.go @@ -17,6 +17,7 @@ import ( tfevents "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/cloudwatchevents" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/cloudwatchevents/finder" iamwaiter "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/waiter" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) const ( @@ -29,6 +30,7 @@ func resourceAwsCloudWatchEventRule() *schema.Resource { Read: resourceAwsCloudWatchEventRuleRead, Update: resourceAwsCloudWatchEventRuleUpdate, Delete: resourceAwsCloudWatchEventRuleDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -108,8 +110,9 @@ func resourceAwsCloudWatchEventRuleCreate(d *schema.ResourceData, meta interface name := naming.Generate(d.Get("name").(string), d.Get("name_prefix").(string)) input, err := buildPutRuleInputStruct(d, name) + if err != nil { - return fmt.Errorf("Creating CloudWatch Events Rule failed: %w", err) + return err } if len(tags) > 0 { @@ -117,35 +120,30 @@ func resourceAwsCloudWatchEventRuleCreate(d *schema.ResourceData, meta interface } log.Printf("[DEBUG] Creating CloudWatch Events Rule: %s", input) - // IAM Roles take some time to propagate - var out *events.PutRuleOutput err = resource.Retry(iamwaiter.PropagationTimeout, func() *resource.RetryError { - out, err = conn.PutRule(input) + _, err = conn.PutRule(input) - if isAWSErr(err, "ValidationException", "cannot be assumed by principal") { - log.Printf("[DEBUG] Retrying update of CloudWatch Events Rule %q", aws.StringValue(input.Name)) + if tfawserr.ErrMessageContains(err, "ValidationException", "cannot be assumed by principal") { return resource.RetryableError(err) } + if err != nil { return resource.NonRetryableError(err) } + return nil }) - if isResourceTimeoutError(err) { - out, err = conn.PutRule(input) + + if tfresource.TimedOut(err) { + _, err = conn.PutRule(input) } if err != nil { - return fmt.Errorf("Creating CloudWatch Events Rule failed: %w", err) + return fmt.Errorf("error creating CloudWatch Events Rule (%s): %w", name, err) } - d.Set("arn", out.RuleArn) - - id := tfevents.RuleCreateResourceID(aws.StringValue(input.EventBusName), aws.StringValue(input.Name)) - d.SetId(id) - - log.Printf("[INFO] CloudWatch Events Rule (%s) created", aws.StringValue(out.RuleArn)) + d.SetId(tfevents.RuleCreateResourceID(aws.StringValue(input.EventBusName), aws.StringValue(input.Name))) return resourceAwsCloudWatchEventRuleRead(d, meta) } @@ -155,39 +153,47 @@ func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{} defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig - out, err := finder.RuleByID(conn, d.Id()) - if tfawserr.ErrCodeEquals(err, events.ErrCodeResourceNotFoundException) { - log.Printf("[WARN] Removing CloudWatch Events Rule (%s) because it's gone.", d.Id()) + eventBusName, ruleName, err := tfevents.RuleParseResourceID(d.Id()) + + if err != nil { + return err + } + + output, err := finder.RuleByEventBusAndRuleNames(conn, eventBusName, ruleName) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] CloudWatch Events Rule (%s) not found, removing from state", d.Id()) d.SetId("") return nil } + if err != nil { return fmt.Errorf("error reading CloudWatch Events Rule (%s): %w", d.Id(), err) } - log.Printf("[DEBUG] Found Event Rule: %s", out) - arn := aws.StringValue(out.Arn) + arn := aws.StringValue(output.Arn) d.Set("arn", arn) - d.Set("description", out.Description) - if out.EventPattern != nil { - pattern, err := structure.NormalizeJsonString(aws.StringValue(out.EventPattern)) + d.Set("description", output.Description) + if output.EventPattern != nil { + pattern, err := structure.NormalizeJsonString(aws.StringValue(output.EventPattern)) if err != nil { return fmt.Errorf("event pattern contains an invalid JSON: %w", err) } d.Set("event_pattern", pattern) } - d.Set("name", out.Name) - d.Set("name_prefix", naming.NamePrefixFromName(aws.StringValue(out.Name))) - d.Set("role_arn", out.RoleArn) - d.Set("schedule_expression", out.ScheduleExpression) - d.Set("event_bus_name", out.EventBusName) + d.Set("name", output.Name) + d.Set("name_prefix", naming.NamePrefixFromName(aws.StringValue(output.Name))) + d.Set("role_arn", output.RoleArn) + d.Set("schedule_expression", output.ScheduleExpression) + d.Set("event_bus_name", eventBusName) // Use event bus name from resource ID as API response may collapse any ARN. + + enabled, err := tfevents.RuleEnabledFromState(aws.StringValue(output.State)) - boolState, err := getBooleanStateFromString(*out.State) if err != nil { return err } - log.Printf("[DEBUG] Setting boolean state: %t", boolState) - d.Set("is_enabled", boolState) + + d.Set("is_enabled", enabled) tags, err := keyvaluetags.CloudwatcheventsListTags(conn, arn) @@ -211,35 +217,40 @@ func resourceAwsCloudWatchEventRuleRead(d *schema.ResourceData, meta interface{} func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn + _, ruleName, err := tfevents.RuleParseResourceID(d.Id()) + if err != nil { return err } + input, err := buildPutRuleInputStruct(d, ruleName) + if err != nil { - return fmt.Errorf("Updating CloudWatch Events Rule (%s) failed: %w", ruleName, err) + return err } - log.Printf("[DEBUG] Updating CloudWatch Events Rule: %s", input) // IAM Roles take some time to propagate err = resource.Retry(iamwaiter.PropagationTimeout, func() *resource.RetryError { _, err := conn.PutRule(input) - if isAWSErr(err, "ValidationException", "cannot be assumed by principal") { - log.Printf("[DEBUG] Retrying update of CloudWatch Events Rule %q", aws.StringValue(input.Name)) + if tfawserr.ErrMessageContains(err, "ValidationException", "cannot be assumed by principal") { return resource.RetryableError(err) } + if err != nil { return resource.NonRetryableError(err) } + return nil }) - if isResourceTimeoutError(err) { + + if tfresource.TimedOut(err) { _, err = conn.PutRule(input) } if err != nil { - return fmt.Errorf("Updating CloudWatch Events Rule (%s) failed: %w", ruleName, err) + return fmt.Errorf("error updating CloudWatch Events Rule (%s): %w", d.Id(), err) } arn := d.Get("arn").(string) @@ -256,19 +267,25 @@ func resourceAwsCloudWatchEventRuleUpdate(d *schema.ResourceData, meta interface func resourceAwsCloudWatchEventRuleDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudwatcheventsconn - busName, ruleName, err := tfevents.RuleParseResourceID(d.Id()) + + eventBusName, ruleName, err := tfevents.RuleParseResourceID(d.Id()) + if err != nil { return err } + input := &events.DeleteRuleInput{ - Name: aws.String(ruleName), - EventBusName: aws.String(busName), + Name: aws.String(ruleName), + } + if eventBusName != "" { + input.EventBusName = aws.String(eventBusName) } + log.Printf("[DEBUG] Deleting CloudWatch Events Rule: %s", d.Id()) err = resource.Retry(cloudWatchEventRuleDeleteRetryTimeout, func() *resource.RetryError { _, err := conn.DeleteRule(input) - if isAWSErr(err, "ValidationException", "Rule can't be deleted since it has targets") { + if tfawserr.ErrMessageContains(err, "ValidationException", "Rule can't be deleted since it has targets") { return resource.RetryableError(err) } @@ -279,10 +296,14 @@ func resourceAwsCloudWatchEventRuleDelete(d *schema.ResourceData, meta interface return nil }) - if isResourceTimeoutError(err) { + if tfresource.TimedOut(err) { _, err = conn.DeleteRule(input) } + if tfawserr.ErrCodeEquals(err, events.ErrCodeResourceNotFoundException) { + return nil + } + if err != nil { return fmt.Errorf("error deleting CloudWatch Events Rule (%s): %w", d.Id(), err) } @@ -316,31 +337,11 @@ func buildPutRuleInputStruct(d *schema.ResourceData, name string) (*events.PutRu input.ScheduleExpression = aws.String(v.(string)) } - input.State = aws.String(getStringStateFromBoolean(d.Get("is_enabled").(bool))) + input.State = aws.String(tfevents.RuleStateFromEnabled(d.Get("is_enabled").(bool))) return &input, nil } -// State is represented as (ENABLED|DISABLED) in the API -func getBooleanStateFromString(state string) (bool, error) { - if state == events.RuleStateEnabled { - return true, nil - } else if state == events.RuleStateDisabled { - return false, nil - } - // We don't just blindly trust AWS as they tend to return - // unexpected values in similar cases (different casing etc.) - return false, fmt.Errorf("Failed converting state %q into boolean", state) -} - -// State is represented as (ENABLED|DISABLED) in the API -func getStringStateFromBoolean(isEnabled bool) string { - if isEnabled { - return events.RuleStateEnabled - } - return events.RuleStateDisabled -} - func validateEventPatternValue() schema.SchemaValidateFunc { return func(v interface{}, k string) (ws []string, errors []error) { json, err := structure.NormalizeJsonString(v) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index aaa4a173f09a..faf4849875cc 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -16,6 +16,7 @@ import ( "github.com/terraform-providers/terraform-provider-aws/aws/internal/naming" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/cloudwatchevents/finder" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/cloudwatchevents/lister" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func init() { @@ -548,7 +549,7 @@ func TestAccAWSCloudWatchEventRule_EventBusArn(t *testing.T) { testAccCheckCloudWatchEventRuleExists(resourceName, &v), testAccMatchResourceAttrRegionalARN(resourceName, "arn", "events", regexp.MustCompile(fmt.Sprintf(`rule/%s/%s$`, eventBusName, rName))), resource.TestCheckResourceAttr(resourceName, "description", ""), - //resource.TestCheckResourceAttrPair(resourceName, "event_bus_name", "aws_cloudwatch_event_bus.test", "arn"), + resource.TestCheckResourceAttrPair(resourceName, "event_bus_name", "aws_cloudwatch_event_bus.test", "arn"), testAccCheckResourceAttrEquivalentJSON(resourceName, "event_pattern", "{\"source\":[\"aws.ec2\"]}"), resource.TestCheckResourceAttr(resourceName, "is_enabled", "true"), resource.TestCheckResourceAttr(resourceName, "name", rName), @@ -573,15 +574,17 @@ func testAccCheckCloudWatchEventRuleExists(n string, rule *events.DescribeRuleOu return fmt.Errorf("Not found: %s", n) } + if rs.Primary.ID == "" { + return fmt.Errorf("No CloudWatch Events Rule ID is set") + } + conn := testAccProvider.Meta().(*AWSClient).cloudwatcheventsconn - resp, err := finder.RuleByID(conn, rs.Primary.ID) + resp, err := finder.RuleByResourceID(conn, rs.Primary.ID) + if err != nil { return err } - if resp == nil { - return fmt.Errorf("CloudWatch Events rule (%s) not found", rs.Primary.ID) - } *rule = *resp @@ -598,10 +601,12 @@ func testAccCheckCloudWatchEventRuleEnabled(n string, desired string) resource.T conn := testAccProvider.Meta().(*AWSClient).cloudwatcheventsconn - resp, err := finder.RuleByID(conn, rs.Primary.ID) + resp, err := finder.RuleByResourceID(conn, rs.Primary.ID) + if err != nil { return err } + if aws.StringValue(resp.State) != desired { return fmt.Errorf("Expected state %q, given %q", desired, aws.StringValue(resp.State)) } @@ -618,10 +623,17 @@ func testAccCheckAWSCloudWatchEventRuleDestroy(s *terraform.State) error { continue } - resp, err := finder.RuleByID(conn, rs.Primary.ID) - if err == nil { - return fmt.Errorf("CloudWatch Events Rule (%s) still exists: %s", rs.Primary.ID, resp) + _, err := finder.RuleByResourceID(conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err } + + return fmt.Errorf("CloudWatch Events Rule %s still exists", rs.Primary.ID) } return nil From 13927fcbc366501f6b236ab28b610e218c51e08d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 18 Aug 2021 15:00:28 -0400 Subject: [PATCH 23/26] r/aws_cloudwatch_event_target: Fix GovCloud test failure. --- aws/resource_aws_cloudwatch_event_target_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index a19e8169afae..f8d62235edf2 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/endpoints" events "github.com/aws/aws-sdk-go/service/cloudwatchevents" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -220,6 +221,11 @@ func TestAccAWSCloudWatchEventTarget_EventBusName(t *testing.T) { } func TestAccAWSCloudWatchEventTarget_EventBusArn(t *testing.T) { + // "ValidationException: Adding an EventBus as a target within an account is not allowed." + if got, want := testAccGetPartition(), endpoints.AwsUsGovPartitionID; got == want { + t.Skipf("CloudWatch Events Target EventBus ARNs are not supported in %s partition", got) + } + resourceName := "aws_cloudwatch_event_target.test" var target events.Target From 6f5e51b3ec0798766316451918b8322fde42e072 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 18 Aug 2021 15:19:03 -0400 Subject: [PATCH 24/26] Fix terrafmt errors. --- ...resource_aws_cloudwatch_event_rule_test.go | 2 +- ...source_aws_cloudwatch_event_target_test.go | 46 +++++++++---------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_rule_test.go b/aws/resource_aws_cloudwatch_event_rule_test.go index faf4849875cc..a913a8dc6c45 100644 --- a/aws/resource_aws_cloudwatch_event_rule_test.go +++ b/aws/resource_aws_cloudwatch_event_rule_test.go @@ -850,7 +850,7 @@ PATTERN func testAccAWSCloudWatchEventRuleEventBusArn(rName, eventBusName string) string { return fmt.Sprintf(` resource "aws_cloudwatch_event_bus" "test" { - name = %[2]q + name = %[2]q } resource "aws_cloudwatch_event_rule" "test" { diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index f8d62235edf2..58df7b5b1d2b 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -991,48 +991,44 @@ func testAccAWSCloudWatchEventTargetConfigEventBusArn(ruleName, originEventBusNa data "aws_partition" "current" {} resource "aws_cloudwatch_event_bus" "test_origin_bus" { - name = %[1]q + name = %[1]q } resource "aws_cloudwatch_event_bus" "test_destination_bus" { - name = %[4]q + name = %[4]q } resource "aws_cloudwatch_event_target" "test" { - rule = aws_cloudwatch_event_rule.test.name - event_bus_name = aws_cloudwatch_event_bus.test_origin_bus.arn - target_id = %[3]q - arn = aws_cloudwatch_event_bus.test_destination_bus.arn - role_arn = aws_iam_role.test.arn + rule = aws_cloudwatch_event_rule.test.name + event_bus_name = aws_cloudwatch_event_bus.test_origin_bus.arn + target_id = %[3]q + arn = aws_cloudwatch_event_bus.test_destination_bus.arn + role_arn = aws_iam_role.test.arn } resource "aws_cloudwatch_event_rule" "test" { - name = %[2]q - event_bus_name = aws_cloudwatch_event_bus.test_origin_bus.name - event_pattern = < Date: Wed, 18 Aug 2021 15:30:42 -0400 Subject: [PATCH 25/26] Fix terrafmt errors. --- 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 58df7b5b1d2b..75cfee630972 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -997,13 +997,13 @@ resource "aws_cloudwatch_event_bus" "test_origin_bus" { resource "aws_cloudwatch_event_bus" "test_destination_bus" { name = %[4]q } - + resource "aws_cloudwatch_event_target" "test" { rule = aws_cloudwatch_event_rule.test.name event_bus_name = aws_cloudwatch_event_bus.test_origin_bus.arn target_id = %[3]q arn = aws_cloudwatch_event_bus.test_destination_bus.arn - role_arn = aws_iam_role.test.arn + role_arn = aws_iam_role.test.arn } resource "aws_cloudwatch_event_rule" "test" { @@ -1018,7 +1018,7 @@ PATTERN resource "aws_iam_role" "test" { name = %[5]q - + assume_role_policy = < Date: Wed, 18 Aug 2021 15:40:58 -0400 Subject: [PATCH 26/26] Fix terrafmt errors. --- aws/resource_aws_cloudwatch_event_target_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index 75cfee630972..fe63a99cf9d1 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -1003,7 +1003,7 @@ resource "aws_cloudwatch_event_target" "test" { event_bus_name = aws_cloudwatch_event_bus.test_origin_bus.arn target_id = %[3]q arn = aws_cloudwatch_event_bus.test_destination_bus.arn - role_arn = aws_iam_role.test.arn + role_arn = aws_iam_role.test.arn } resource "aws_cloudwatch_event_rule" "test" {