Skip to content

Commit

Permalink
resource/aws_cloudwatch_event_target: Prevent potential panic and pas…
Browse files Browse the repository at this point in the history
…sthrough custom event_bus_name in v0 state upgrade

Reference: #16394

If a configuration was applied with version 3.14.0, the `event_bus_name` attribute could have a custom value and the state upgrader function would previously not pass it through.

Previous output from new unit test:

```
--- FAIL: TestResourceAwsCloudWatchEventTargetStateUpgradeV0EventBusName (0.00s)
    resource_aws_cloudwatch_event_target_migrate_test.go:66:

        expected:

        map[string]interface {}{"arn":"arn:aws:test:us-east-1:123456789012:test", "event_bus_name":"testbus", "rule":"testrule", "target_id":"testtargetid"}

        got:

        map[string]interface {}{"arn":"arn:aws:test:us-east-1:123456789012:test", "event_bus_name":"default", "rule":"testrule", "target_id":"testtargetid"}
```

Given this configuration:

```terraform
terraform {
  required_providers {
    aws = "3.14.0"
  }
  required_version = "0.12.29"
}

provider "aws" {
  region = "us-east-2"
}

resource "aws_cloudwatch_event_bus" "test" {
  name = "16394-test"
}

resource "aws_cloudwatch_event_rule" "test" {
  event_bus_name = aws_cloudwatch_event_bus.test.name
  event_pattern = jsonencode({
    source = ["aws.ec2"]
  })
  name = "16394-test"
}

resource "aws_cloudwatch_event_target" "test" {
  arn            = aws_sns_topic.test.arn
  event_bus_name = aws_cloudwatch_event_bus.test.name
  rule           = aws_cloudwatch_event_rule.test.name
  target_id      = "16394-test"
}

resource "aws_sns_topic" "test" {
  name = "16394-test"
}
```

Output from console:

```console
$ terraform init
...
$ terraform apply
...
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
# edit provider version to 3.18.0
$ terraform init
...
$ terraform apply
...
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_cloudwatch_event_target.test will be created
  + resource "aws_cloudwatch_event_target" "test" {
      + arn            = "arn:aws:sns:us-east-2:--OMITTED--:16394-test"
      + event_bus_name = "16394-test"
      + id             = (known after apply)
      + rule           = "16394-test"
      + target_id      = "16394-test"
    }

Plan: 1 to add, 0 to change, 0 to destroy.
# swap in built Terraform AWS Provider binary
$ terraform apply
...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
```

Output from acceptance testing:

```
--- PASS: TestAccAWSCloudWatchEventTarget_basic (35.74s)
--- PASS: TestAccAWSCloudWatchEventTarget_batch (140.33s)
--- PASS: TestAccAWSCloudWatchEventTarget_disappears (17.51s)
--- PASS: TestAccAWSCloudWatchEventTarget_ecs (28.63s)
--- PASS: TestAccAWSCloudWatchEventTarget_ecsWithBlankTaskCount (31.25s)
--- PASS: TestAccAWSCloudWatchEventTarget_EventBusName (32.01s)
--- PASS: TestAccAWSCloudWatchEventTarget_full (59.07s)
--- PASS: TestAccAWSCloudWatchEventTarget_GeneratedTargetId (16.62s)
--- PASS: TestAccAWSCloudWatchEventTarget_input_transformer (47.34s)
--- PASS: TestAccAWSCloudWatchEventTarget_inputTransformerJsonString (38.99s)
--- PASS: TestAccAWSCloudWatchEventTarget_kinesis (59.09s)
--- PASS: TestAccAWSCloudWatchEventTarget_sqs (16.71s)
--- PASS: TestAccAWSCloudWatchEventTarget_ssmDocument (18.77s)
```
  • Loading branch information
bflad committed Nov 30, 2020
1 parent 2a00b8f commit 54d91a2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
8 changes: 7 additions & 1 deletion aws/resource_aws_cloudwatch_event_target_migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,13 @@ func resourceAwsCloudWatchEventTargetV0() *schema.Resource {
}

func resourceAwsCloudWatchEventTargetStateUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
rawState["event_bus_name"] = tfevents.DefaultEventBusName
if rawState == nil {
rawState = map[string]interface{}{}
}

if _, ok := rawState["event_bus_name"]; !ok {
rawState["event_bus_name"] = tfevents.DefaultEventBusName
}

return rawState, nil
}
31 changes: 31 additions & 0 deletions aws/resource_aws_cloudwatch_event_target_migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ func testResourceAwsCloudWatchEventTargetStateDataV0() map[string]interface{} {
}
}

func testResourceAwsCloudWatchEventTargetStateDataV0EventBusName() map[string]interface{} {
return map[string]interface{}{
"arn": "arn:aws:test:us-east-1:123456789012:test", //lintignore:AWSAT003,AWSAT005
"event_bus_name": "testbus",
"rule": "testrule",
"target_id": "testtargetid",
}
}

func testResourceAwsCloudWatchEventTargetStateDataV1() map[string]interface{} {
v0 := testResourceAwsCloudWatchEventTargetStateDataV0()
return map[string]interface{}{
Expand All @@ -24,6 +33,16 @@ func testResourceAwsCloudWatchEventTargetStateDataV1() map[string]interface{} {
}
}

func testResourceAwsCloudWatchEventTargetStateDataV1EventBusName() map[string]interface{} {
v0 := testResourceAwsCloudWatchEventTargetStateDataV0EventBusName()
return map[string]interface{}{
"arn": v0["arn"],
"event_bus_name": v0["event_bus_name"],
"rule": v0["rule"],
"target_id": v0["target_id"],
}
}

func TestResourceAwsCloudWatchEventTargetStateUpgradeV0(t *testing.T) {
expected := testResourceAwsCloudWatchEventTargetStateDataV1()
actual, err := resourceAwsCloudWatchEventTargetStateUpgradeV0(context.Background(), testResourceAwsCloudWatchEventTargetStateDataV0(), nil)
Expand All @@ -35,3 +54,15 @@ func TestResourceAwsCloudWatchEventTargetStateUpgradeV0(t *testing.T) {
t.Fatalf("\n\nexpected:\n\n%#v\n\ngot:\n\n%#v\n\n", expected, actual)
}
}

func TestResourceAwsCloudWatchEventTargetStateUpgradeV0EventBusName(t *testing.T) {
expected := testResourceAwsCloudWatchEventTargetStateDataV1EventBusName()
actual, err := resourceAwsCloudWatchEventTargetStateUpgradeV0(context.Background(), testResourceAwsCloudWatchEventTargetStateDataV0EventBusName(), nil)
if err != nil {
t.Fatalf("error migrating state: %s", err)
}

if !reflect.DeepEqual(expected, actual) {
t.Fatalf("\n\nexpected:\n\n%#v\n\ngot:\n\n%#v\n\n", expected, actual)
}
}

0 comments on commit 54d91a2

Please sign in to comment.