diff --git a/.changelog/14101.txt b/.changelog/14101.txt new file mode 100644 index 00000000000..17b056ebb9c --- /dev/null +++ b/.changelog/14101.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/aws_sns_topic_subscription: Add plan time validation for `subscription_role_arn` and `topic_arn` +``` + +```release-note:bug +resource/aws_sns_topic_subscription: recreate subscription if topic is deleted +``` \ No newline at end of file diff --git a/aws/internal/service/sns/finder/finder.go b/aws/internal/service/sns/finder/finder.go new file mode 100644 index 00000000000..79628328ebf --- /dev/null +++ b/aws/internal/service/sns/finder/finder.go @@ -0,0 +1,26 @@ +package finder + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/sns" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" +) + +func SubscriptionByARN(conn *sns.SNS, id string) (*sns.GetSubscriptionAttributesOutput, error) { + output, err := conn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{ + SubscriptionArn: aws.String(id), + }) + if tfawserr.ErrCodeEquals(err, sns.ErrCodeNotFoundException) { + return nil, nil + } + + if err != nil { + return nil, err + } + + if output == nil || output.Attributes == nil || len(output.Attributes) == 0 { + return nil, nil + } + + return output, nil +} diff --git a/aws/internal/service/sns/waiter/status.go b/aws/internal/service/sns/waiter/status.go index 31013219404..45e2f163327 100644 --- a/aws/internal/service/sns/waiter/status.go +++ b/aws/internal/service/sns/waiter/status.go @@ -3,20 +3,13 @@ package waiter import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/sns" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sns/finder" ) func SubscriptionPendingConfirmation(conn *sns.SNS, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - output, err := conn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{ - SubscriptionArn: aws.String(id), - }) - - if tfawserr.ErrCodeEquals(err, sns.ErrCodeResourceNotFoundException) { - return nil, "", nil - } - + output, err := finder.SubscriptionByARN(conn, id) if err != nil { return nil, "", err } diff --git a/aws/internal/service/sns/waiter/waiter.go b/aws/internal/service/sns/waiter/waiter.go index fb7c5a85008..efd75f3ed49 100644 --- a/aws/internal/service/sns/waiter/waiter.go +++ b/aws/internal/service/sns/waiter/waiter.go @@ -9,6 +9,7 @@ import ( const ( SubscriptionPendingConfirmationTimeout = 2 * time.Minute + SubscriptionDeleteTimeout = 2 * time.Minute ) func SubscriptionConfirmed(conn *sns.SNS, id, expectedValue string, timeout time.Duration) (*sns.GetSubscriptionAttributesOutput, error) { @@ -26,3 +27,20 @@ func SubscriptionConfirmed(conn *sns.SNS, id, expectedValue string, timeout time return nil, err } + +func SubscriptionDeleted(conn *sns.SNS, id string) (*sns.GetSubscriptionAttributesOutput, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{"false", "true"}, + Target: []string{}, + Refresh: SubscriptionPendingConfirmation(conn, id), + Timeout: SubscriptionDeleteTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*sns.GetSubscriptionAttributesOutput); ok { + return output, err + } + + return nil, err +} diff --git a/aws/resource_aws_sns_topic_subscription.go b/aws/resource_aws_sns_topic_subscription.go index 99d7ff0578a..c970dfded66 100644 --- a/aws/resource_aws_sns_topic_subscription.go +++ b/aws/resource_aws_sns_topic_subscription.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sns/finder" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sns/waiter" ) @@ -104,13 +105,15 @@ func resourceAwsSnsTopicSubscription() *schema.Resource { DiffSuppressFunc: suppressEquivalentJsonDiffs, }, "subscription_role_arn": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateArn, }, "topic_arn": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateArn, }, }, } @@ -168,22 +171,27 @@ func resourceAwsSnsTopicSubscriptionRead(d *schema.ResourceData, meta interface{ log.Printf("[DEBUG] Loading subscription %s", d.Id()) - output, err := conn.GetSubscriptionAttributes(&sns.GetSubscriptionAttributesInput{ - SubscriptionArn: aws.String(d.Id()), - }) + input := &sns.ListSubscriptionsByTopicInput{ + TopicArn: aws.String(d.Get("topic_arn").(string)), + } - if !d.IsNewResource() && (tfawserr.ErrCodeEquals(err, sns.ErrCodeResourceNotFoundException) || tfawserr.ErrCodeEquals(err, sns.ErrCodeNotFoundException)) { - log.Printf("[WARN] SNS subscription attributes (%s) not found, removing from state", d.Id()) + _, err := conn.ListSubscriptionsByTopic(input) + + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, sns.ErrCodeNotFoundException) { + log.Printf("[WARN] SNS Topic Subscription (%s) not found, removing from state", d.Id()) d.SetId("") return nil } + output, err := finder.SubscriptionByARN(conn, d.Id()) if err != nil { return fmt.Errorf("getting SNS subscription attributes (%s): %w", d.Id(), err) } - if output == nil || output.Attributes == nil || len(output.Attributes) == 0 { - return fmt.Errorf("getting SNS subscription attributes (%s): empty response", d.Id()) + if output == nil { + log.Printf("[WARN] SNS subscription attributes (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil } attributes := output.Attributes @@ -282,6 +290,13 @@ func resourceAwsSnsTopicSubscriptionDelete(d *schema.ResourceData, meta interfac return nil } + if _, err := waiter.SubscriptionDeleted(conn, d.Id()); err != nil { + if tfawserr.ErrCodeEquals(err, sns.ErrCodeNotFoundException) { + return nil + } + return fmt.Errorf("error waiting for SNS topic subscription (%s) deletion: %w", d.Id(), err) + } + return err } diff --git a/aws/resource_aws_sns_topic_subscription_test.go b/aws/resource_aws_sns_topic_subscription_test.go index afc2f08a5f0..96acaa1e0c2 100644 --- a/aws/resource_aws_sns_topic_subscription_test.go +++ b/aws/resource_aws_sns_topic_subscription_test.go @@ -12,11 +12,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/sns" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/sns/finder" ) func TestSuppressEquivalentSnsTopicSubscriptionDeliveryPolicy(t *testing.T) { @@ -67,7 +67,7 @@ func TestSuppressEquivalentSnsTopicSubscriptionDeliveryPolicy(t *testing.T) { func TestAccAWSSNSTopicSubscription_basic(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -83,12 +83,12 @@ func TestAccAWSSNSTopicSubscription_basic(t *testing.T) { testAccMatchResourceAttrRegionalARN(resourceName, "arn", sns.ServiceName, regexp.MustCompile(fmt.Sprintf("%s:.+", rName))), resource.TestCheckResourceAttr(resourceName, "confirmation_was_authenticated", "true"), resource.TestCheckResourceAttr(resourceName, "delivery_policy", ""), - resource.TestCheckResourceAttrPair(resourceName, "endpoint", "aws_sqs_queue.test_queue", "arn"), + resource.TestCheckResourceAttrPair(resourceName, "endpoint", "aws_sqs_queue.test", "arn"), resource.TestCheckResourceAttr(resourceName, "filter_policy", ""), resource.TestCheckResourceAttr(resourceName, "pending_confirmation", "false"), resource.TestCheckResourceAttr(resourceName, "protocol", "sqs"), resource.TestCheckResourceAttr(resourceName, "raw_message_delivery", "false"), - resource.TestCheckResourceAttrPair(resourceName, "topic_arn", "aws_sns_topic.test_topic", "arn"), + resource.TestCheckResourceAttrPair(resourceName, "topic_arn", "aws_sns_topic.test", "arn"), ), }, { @@ -106,7 +106,7 @@ func TestAccAWSSNSTopicSubscription_basic(t *testing.T) { func TestAccAWSSNSTopicSubscription_filterPolicy(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" filterPolicy1 := `{"key1": ["val1"], "key2": ["val2"]}` filterPolicy2 := `{"key3": ["val3"], "key4": ["val4"]}` rName := acctest.RandomWithPrefix("tf-acc-test") @@ -155,7 +155,7 @@ func TestAccAWSSNSTopicSubscription_filterPolicy(t *testing.T) { func TestAccAWSSNSTopicSubscription_deliveryPolicy(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -214,7 +214,7 @@ func TestAccAWSSNSTopicSubscription_deliveryPolicy(t *testing.T) { func TestAccAWSSNSTopicSubscription_redrivePolicy(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" dlqName := acctest.RandomWithPrefix("tf-acc-test") updatedDlqName := acctest.RandomWithPrefix("tf-acc-test") rName := acctest.RandomWithPrefix("tf-acc-test") @@ -272,7 +272,7 @@ func TestAccAWSSNSTopicSubscription_redrivePolicy(t *testing.T) { func TestAccAWSSNSTopicSubscription_rawMessageDelivery(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -319,7 +319,7 @@ func TestAccAWSSNSTopicSubscription_rawMessageDelivery(t *testing.T) { func TestAccAWSSNSTopicSubscription_autoConfirmingEndpoint(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -349,7 +349,7 @@ func TestAccAWSSNSTopicSubscription_autoConfirmingEndpoint(t *testing.T) { func TestAccAWSSNSTopicSubscription_autoConfirmingSecuredEndpoint(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -379,7 +379,7 @@ func TestAccAWSSNSTopicSubscription_autoConfirmingSecuredEndpoint(t *testing.T) func TestAccAWSSNSTopicSubscription_email(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -400,7 +400,7 @@ func TestAccAWSSNSTopicSubscription_email(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "pending_confirmation", "true"), resource.TestCheckResourceAttr(resourceName, "protocol", "email"), resource.TestCheckResourceAttr(resourceName, "raw_message_delivery", "false"), - resource.TestCheckResourceAttrPair(resourceName, "topic_arn", "aws_sns_topic.test_topic", "arn"), + resource.TestCheckResourceAttrPair(resourceName, "topic_arn", "aws_sns_topic.test", "arn"), ), }, }, @@ -409,7 +409,7 @@ func TestAccAWSSNSTopicSubscription_email(t *testing.T) { func TestAccAWSSNSTopicSubscription_firehose(t *testing.T) { attributes := make(map[string]string) - resourceName := "aws_sns_topic_subscription.test_subscription" + resourceName := "aws_sns_topic_subscription.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -428,7 +428,7 @@ func TestAccAWSSNSTopicSubscription_firehose(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "filter_policy", ""), resource.TestCheckResourceAttr(resourceName, "protocol", "firehose"), resource.TestCheckResourceAttr(resourceName, "raw_message_delivery", "false"), - resource.TestCheckResourceAttrPair(resourceName, "topic_arn", "aws_sns_topic.test_topic", "arn"), + resource.TestCheckResourceAttrPair(resourceName, "topic_arn", "aws_sns_topic.test", "arn"), resource.TestCheckResourceAttrPair(resourceName, "subscription_role_arn", "aws_iam_role.firehose_role", "arn"), ), }, @@ -436,6 +436,50 @@ func TestAccAWSSNSTopicSubscription_firehose(t *testing.T) { }) } +func TestAccAWSSNSTopicSubscription_disappears(t *testing.T) { + attributes := make(map[string]string) + resourceName := "aws_sns_topic_subscription.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSNSTopicSubscriptionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSNSTopicSubscriptionConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSNSTopicSubscriptionExists(resourceName, attributes), + testAccCheckResourceDisappears(testAccProvider, resourceAwsSnsTopicSubscription(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAWSSNSTopicSubscription_disappears_topic(t *testing.T) { + attributes := make(map[string]string) + resourceName := "aws_sns_topic_subscription.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSNSTopicSubscriptionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSNSTopicSubscriptionConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSNSTopicSubscriptionExists(resourceName, attributes), + testAccCheckResourceDisappears(testAccProvider, resourceAwsSnsTopic(), "aws_sns_topic.test"), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + // testAccErrorCheckSkipSNS skips SNS tests that have error messages indicating unsupported features func testAccErrorCheckSkipSNS(t *testing.T) resource.ErrorCheckFunc { return testAccErrorCheckSkipMessagesContaining(t, @@ -447,26 +491,20 @@ func testAccCheckAWSSNSTopicSubscriptionDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).snsconn for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_sns_topic" { + if rs.Type != "aws_sns_topic_subscription" { continue } - // Try to find key pair - req := &sns.GetSubscriptionAttributesInput{ - SubscriptionArn: aws.String(rs.Primary.ID), + output, err := finder.SubscriptionByARN(conn, rs.Primary.ID) + if err != nil { + return fmt.Errorf("SNS topic subscription still exists, can't continue.") } - _, err := conn.GetSubscriptionAttributes(req) - - if err == nil { - return fmt.Errorf("Subscription still exists, can't continue.") + if output == nil || aws.StringValue(output.Attributes["Protocol"]) == "email" { + return nil } - // Verify the error is an API error, not something else - _, ok := err.(awserr.Error) - if !ok { - return err - } + return fmt.Errorf("SNS topic Subscription (%s) exists when it should be destroyed", rs.Primary.ID) } return nil @@ -485,11 +523,7 @@ func testAccCheckAWSSNSTopicSubscriptionExists(n string, attributes map[string]s conn := testAccProvider.Meta().(*AWSClient).snsconn - params := &sns.GetSubscriptionAttributesInput{ - SubscriptionArn: aws.String(rs.Primary.ID), - } - output, err := conn.GetSubscriptionAttributes(params) - + output, err := finder.SubscriptionByARN(conn, rs.Primary.ID) for k, v := range output.Attributes { attributes[k] = aws.StringValue(v) } @@ -588,105 +622,105 @@ func TestObfuscateEndpointPassword(t *testing.T) { func testAccAWSSNSTopicSubscriptionConfig(rName string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } -resource "aws_sqs_queue" "test_queue" { +resource "aws_sqs_queue" "test" { name = %[1]q } -resource "aws_sns_topic_subscription" "test_subscription" { - topic_arn = aws_sns_topic.test_topic.arn +resource "aws_sns_topic_subscription" "test" { + topic_arn = aws_sns_topic.test.arn protocol = "sqs" - endpoint = aws_sqs_queue.test_queue.arn + endpoint = aws_sqs_queue.test.arn } `, rName) } func testAccAWSSNSTopicSubscriptionConfig_filterPolicy(rName, policy string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } -resource "aws_sqs_queue" "test_queue" { +resource "aws_sqs_queue" "test" { name = %[1]q } -resource "aws_sns_topic_subscription" "test_subscription" { - topic_arn = aws_sns_topic.test_topic.arn +resource "aws_sns_topic_subscription" "test" { + topic_arn = aws_sns_topic.test.arn protocol = "sqs" - endpoint = aws_sqs_queue.test_queue.arn - filter_policy = %s + endpoint = aws_sqs_queue.test.arn + filter_policy = %[2]s } `, rName, policy) } func testAccAWSSNSTopicSubscriptionConfig_deliveryPolicy(rName, policy string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } -resource "aws_sqs_queue" "test_queue" { +resource "aws_sqs_queue" "test" { name = %[1]q } -resource "aws_sns_topic_subscription" "test_subscription" { - delivery_policy = %s - endpoint = aws_sqs_queue.test_queue.arn +resource "aws_sns_topic_subscription" "test" { + delivery_policy = %[2]s + endpoint = aws_sqs_queue.test.arn protocol = "sqs" - topic_arn = aws_sns_topic.test_topic.arn + topic_arn = aws_sns_topic.test.arn } `, rName, policy) } func testAccAWSSNSTopicSubscriptionConfig_redrivePolicy(rName, dlqName string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } -resource "aws_sqs_queue" "test_queue" { +resource "aws_sqs_queue" "test" { name = %[1]q } -resource "aws_sqs_queue" "test_queue_dlq" { +resource "aws_sqs_queue" "test_dlq" { name = %[2]q } -resource "aws_sns_topic_subscription" "test_subscription" { - redrive_policy = jsonencode({ deadLetterTargetArn : aws_sqs_queue.test_queue_dlq.arn }) - endpoint = aws_sqs_queue.test_queue.arn +resource "aws_sns_topic_subscription" "test" { + redrive_policy = jsonencode({ deadLetterTargetArn : aws_sqs_queue.test_dlq.arn }) + endpoint = aws_sqs_queue.test.arn protocol = "sqs" - topic_arn = aws_sns_topic.test_topic.arn + topic_arn = aws_sns_topic.test.arn } `, rName, dlqName) } func testAccAWSSNSTopicSubscriptionConfig_rawMessageDelivery(rName string, rawMessageDelivery bool) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } -resource "aws_sqs_queue" "test_queue" { +resource "aws_sqs_queue" "test" { name = %[1]q } -resource "aws_sns_topic_subscription" "test_subscription" { - endpoint = aws_sqs_queue.test_queue.arn +resource "aws_sns_topic_subscription" "test" { + endpoint = aws_sqs_queue.test.arn protocol = "sqs" - raw_message_delivery = %t - topic_arn = aws_sns_topic.test_topic.arn + raw_message_delivery = %[2]t + topic_arn = aws_sns_topic.test.arn } `, rName, rawMessageDelivery) } func testAccAWSSNSTopicSubscriptionConfig_autoConfirmingEndpoint(rName string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } @@ -799,9 +833,9 @@ resource "aws_api_gateway_deployment" "test" { stage_name = "acctest" } -resource "aws_sns_topic_subscription" "test_subscription" { +resource "aws_sns_topic_subscription" "test" { depends_on = [aws_lambda_permission.apigw_lambda] - topic_arn = aws_sns_topic.test_topic.arn + topic_arn = aws_sns_topic.test.arn protocol = "https" endpoint = aws_api_gateway_deployment.test.invoke_url endpoint_auto_confirms = true @@ -811,7 +845,7 @@ resource "aws_sns_topic_subscription" "test_subscription" { func testAccAWSSNSTopicSubscriptionConfig_autoConfirmingSecuredEndpoint(rName string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } @@ -1001,9 +1035,9 @@ resource "aws_api_gateway_gateway_response" "test" { } } -resource "aws_sns_topic_subscription" "test_subscription" { +resource "aws_sns_topic_subscription" "test" { depends_on = [aws_lambda_permission.apigw_lambda] - topic_arn = aws_sns_topic.test_topic.arn + topic_arn = aws_sns_topic.test.arn protocol = "https" endpoint = replace(aws_api_gateway_deployment.test.invoke_url, "https://", "https://davematthews:granny@") endpoint_auto_confirms = true @@ -1013,12 +1047,12 @@ resource "aws_sns_topic_subscription" "test_subscription" { func testAccAWSSNSTopicSubscriptionEmailConfig(rName string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } -resource "aws_sns_topic_subscription" "test_subscription" { - topic_arn = aws_sns_topic.test_topic.arn +resource "aws_sns_topic_subscription" "test" { + topic_arn = aws_sns_topic.test.arn protocol = "email" endpoint = "invalid_email@example.com" } @@ -1027,14 +1061,14 @@ resource "aws_sns_topic_subscription" "test_subscription" { func testAccAWSSNSTopicSubscriptionConfig_firehose(rName string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "test_topic" { +resource "aws_sns_topic" "test" { name = %[1]q } -resource "aws_sns_topic_subscription" "test_subscription" { +resource "aws_sns_topic_subscription" "test" { endpoint = aws_kinesis_firehose_delivery_stream.test_stream.arn protocol = "firehose" - topic_arn = aws_sns_topic.test_topic.arn + topic_arn = aws_sns_topic.test.arn subscription_role_arn = aws_iam_role.firehose_role.arn } resource "aws_s3_bucket" "bucket" {