Skip to content

Commit

Permalink
Merge pull request #20467 from hashicorp/t-iottopic-test-failures
Browse files Browse the repository at this point in the history
r/iot_topic_rule: add iamwaiter propagation timeout during creation
  • Loading branch information
anGie44 authored Aug 6, 2021
2 parents e4b5382 + 2b4fbfb commit a9ee63d
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 43 deletions.
3 changes: 3 additions & 0 deletions .changelog/20467.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_iot_topic_rule: Enhance handling of IAM eventual consistency errors during create
```
23 changes: 22 additions & 1 deletion aws/resource_aws_iot_topic_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iot"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
iamwaiter "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/waiter"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func resourceAwsIotTopicRule() *schema.Resource {
Expand Down Expand Up @@ -1094,7 +1098,24 @@ func resourceAwsIotTopicRuleCreate(d *schema.ResourceData, meta interface{}) err
TopicRulePayload: expandIotTopicRulePayload(d),
}

_, err := conn.CreateTopicRule(input)
err := resource.Retry(iamwaiter.PropagationTimeout, func() *resource.RetryError {
var err error
_, err = conn.CreateTopicRule(input)

if tfawserr.ErrMessageContains(err, iot.ErrCodeInvalidRequestException, "unable to perform: sts:AssumeRole on resource") {
return resource.RetryableError(err)
}

if err != nil {
return resource.NonRetryableError(err)
}

return nil
})

if tfresource.TimedOut(err) {
_, err = conn.CreateTopicRule(input)
}

if err != nil {
return fmt.Errorf("error creating IoT Topic Rule (%s): %w", ruleName, err)
Expand Down
124 changes: 82 additions & 42 deletions aws/resource_aws_iot_topic_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,8 @@ func testAccCheckAWSIoTTopicRuleExists(name string) resource.TestCheckFunc {
}
}

const testAccAWSIoTTopicRuleRole = `
func testAccAWSIoTTopicRuleRole(rName string) string {
return fmt.Sprintf(`
data "aws_partition" "current" {}
resource "aws_iam_role" "iot_role" {
Expand Down Expand Up @@ -722,10 +723,11 @@ resource "aws_iam_policy_attachment" "attach_policy" {
roles = [aws_iam_role.iot_role.name]
policy_arn = aws_iam_policy.policy.arn
}
`
`, rName)
}

func testAccAWSIoTTopicRule_basic(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -737,7 +739,9 @@ resource "aws_iot_topic_rule" "rule" {
}

func testAccAWSIoTTopicRule_cloudwatchalarm(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -752,11 +756,13 @@ resource "aws_iot_topic_rule" "rule" {
state_value = "OK"
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_cloudwatchmetric(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -772,11 +778,13 @@ resource "aws_iot_topic_rule" "rule" {
role_arn = aws_iam_role.iot_role.arn
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_dynamoDbv2(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -792,11 +800,13 @@ resource "aws_iot_topic_rule" "rule" {
role_arn = aws_iam_role.iot_role.arn
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_dynamodb(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -812,11 +822,13 @@ resource "aws_iot_topic_rule" "rule" {
table_name = "table_name"
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_dynamodb_rangekeys(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -836,11 +848,13 @@ resource "aws_iot_topic_rule" "rule" {
operation = "INSERT"
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_elasticsearch(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
data "aws_region" "current" {}
resource "aws_iot_topic_rule" "rule" {
Expand All @@ -858,11 +872,13 @@ resource "aws_iot_topic_rule" "rule" {
role_arn = aws_iam_role.iot_role.arn
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_firehose(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -875,11 +891,13 @@ resource "aws_iot_topic_rule" "rule" {
role_arn = aws_iam_role.iot_role.arn
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_firehose_separator(rName, separator string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -893,11 +911,13 @@ resource "aws_iot_topic_rule" "rule" {
separator = %q
}
}
`, rName, separator)
`, rName, separator))
}

func testAccAWSIoTTopicRule_kinesis(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -910,13 +930,15 @@ resource "aws_iot_topic_rule" "rule" {
role_arn = aws_iam_role.iot_role.arn
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_lambda(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return fmt.Sprintf(`
data "aws_region" "current" {}
data "aws_partition" "current" {}
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -932,7 +954,9 @@ resource "aws_iot_topic_rule" "rule" {
}

func testAccAWSIoTTopicRule_republish(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -945,11 +969,13 @@ resource "aws_iot_topic_rule" "rule" {
topic = "mytopic"
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_republish_with_qos(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -963,11 +989,13 @@ resource "aws_iot_topic_rule" "rule" {
qos = 1
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_s3(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -981,11 +1009,13 @@ resource "aws_iot_topic_rule" "rule" {
role_arn = aws_iam_role.iot_role.arn
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_sns(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
data "aws_region" "current" {}
resource "aws_iot_topic_rule" "rule" {
Expand All @@ -1000,11 +1030,13 @@ resource "aws_iot_topic_rule" "rule" {
target_arn = "arn:${data.aws_partition.current.partition}:sns:${data.aws_region.current.name}:123456789012:my_corporate_topic"
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_sqs(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -1018,11 +1050,13 @@ resource "aws_iot_topic_rule" "rule" {
use_base64 = false
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_step_functions(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -1036,11 +1070,13 @@ resource "aws_iot_topic_rule" "rule" {
role_arn = aws_iam_role.iot_role.arn
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_iot_analytics(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -1053,11 +1089,13 @@ resource "aws_iot_topic_rule" "rule" {
role_arn = aws_iam_role.iot_role.arn
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRule_iot_events(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -1071,11 +1109,11 @@ resource "aws_iot_topic_rule" "rule" {
message_id = "fake_message_id"
}
}
`, rName)
`, rName))
}

func testAccAWSIoTTopicRuleTags1(rName, tagKey1, tagValue1 string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return fmt.Sprintf(`
resource "aws_iot_topic_rule" "test" {
name = "test_rule_%[1]s"
enabled = true
Expand All @@ -1090,7 +1128,7 @@ resource "aws_iot_topic_rule" "test" {
}

func testAccAWSIoTTopicRuleTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return fmt.Sprintf(`
resource "aws_iot_topic_rule" "test" {
name = "test_rule_%[1]s"
enabled = true
Expand All @@ -1106,7 +1144,9 @@ resource "aws_iot_topic_rule" "test" {
}

func testAccAWSIoTTopicRule_errorAction(rName string) string {
return fmt.Sprintf(testAccAWSIoTTopicRuleRole+`
return composeConfig(
testAccAWSIoTTopicRuleRole(rName),
fmt.Sprintf(`
resource "aws_iot_topic_rule" "rule" {
name = "test_rule_%[1]s"
description = "Example rule"
Expand All @@ -1126,5 +1166,5 @@ resource "aws_iot_topic_rule" "rule" {
}
}
}
`, rName)
`, rName))
}

0 comments on commit a9ee63d

Please sign in to comment.