-
Notifications
You must be signed in to change notification settings - Fork 157
/
Copy path0052-non-idempotent-sns-topic-creation.patch
59 lines (53 loc) · 1.93 KB
/
0052-non-idempotent-sns-topic-creation.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: corymhall <[email protected]>
Date: Thu, 11 Apr 2024 14:42:01 -0400
Subject: [PATCH] non-idempotent sns topic creation
diff --git a/internal/service/sns/topic.go b/internal/service/sns/topic.go
index 17c78c35c1..0d2e35b695 100644
--- a/internal/service/sns/topic.go
+++ b/internal/service/sns/topic.go
@@ -9,6 +9,7 @@ import (
"fmt"
"log"
"regexp"
+ "sync"
"time"
"github.com/YakDriver/regexache"
@@ -260,6 +261,12 @@ func resourceTopic() *schema.Resource {
}
}
+func constructTopicArn(client *sns.Client, account, region, snsTopicName string) string {
+ return fmt.Sprintf("arn:aws:sns:%s:%s:%s", region, account, snsTopicName)
+}
+
+var snsGlobalMutex sync.Map
+
func resourceTopicCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).SNSClient(ctx)
@@ -284,6 +291,27 @@ func resourceTopicCreate(ctx context.Context, d *schema.ResourceData, meta inter
delete(attributes, topicAttributeNameFIFOTopic)
}
+ // create a lock based on the topic ARN. We really want to make sure
+ // that we prevent a race condition where two resources are created with
+ // the same name.
+ topicArn := constructTopicArn(conn, meta.(*conns.AWSClient).AccountID, meta.(*conns.AWSClient).Region, name)
+ localMutex := &sync.Mutex{}
+ if val, ok := snsGlobalMutex.LoadOrStore(topicArn, localMutex); ok {
+ localMutex = val.(*sync.Mutex)
+ }
+ localMutex.Lock()
+ defer localMutex.Unlock()
+
+ // Look up if the topic already exists
+ _, err = findTopicAttributesWithValidAWSPrincipalsByARN(ctx, conn, topicArn)
+
+ if err == nil {
+ return diag.Errorf("SNS Topic (%s) already exists", name)
+ }
+ if !tfresource.NotFound(err) {
+ return diag.FromErr(err)
+ }
+
output, err := conn.CreateTopic(ctx, input)
// Some partitions (e.g. ISO) may not support tag-on-create.