-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for http/https endpoints that auto confirms SNS topic subscription. #4711
Conversation
…ubscription. http and https SNS topic subscription endpoints require confirmation to set a valid arn otherwise arn would be set to "pending confirmation". If the endpoints auto confirm then arn is set asynchronously but if we try to create another subscription with same parameters then api returns "pending subscription" as arn but does not create another a duplicate subscription. In order to solve this we should be fetching the subscription list for the topic and identify the subscription with same parameters i.e., protocol, topic_arn, endpoint and extract the subscription arn. Following changes were made to support the http/https endpoints that auto confirms 1. Added 3 extra parameters i.e., 1. endpoint_auto_confirms -> boolean indicates if end points auto confirms 2. max_fetch_retries -> number of times to fetch subscription list for the topic to get the subscription arn 3. fetch_retry_delay -> delay b/w fetch subscription list call as the confirmation is done asynchronously. With these parameters help added support http and https protocol based endpoints that auto confirm. 2. Update website doc appropriately
max_fetch_retries := d.Get("max_fetch_retries").(int) | ||
fetch_retry_delay := time.Duration(d.Get("fetch_retry_delay").(int)) | ||
|
||
if strings.Contains(protocol, "http") && !endpoint_auto_confirms { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like to move this to validateFunc but I need a function which can give me whole map. I need help on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I see your point. This will be eventually possible after merging #3641 but I wouldn't want to block this PR on that.
The only suggestion I have regarding this is that we should rather be comparing protocols as IDs (i.e. (protocol == "http" || protocol == "https")
), not arbitrary strings.
I almost thought on first sight you forgot about https
.
Also there might be a new service in the future which will actually contain http
in the name and that would make things even more confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I agree that there might be newer protocol which has .http. or .email. etc in it but then I saw logic around line 33 and thought that I should follow on the similar footsteps just to be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the logic around line 33 should be changed too then... if you want to do it, go ahead, but I won't push back on this PR if you won't. It would be nice to get it consistent (and only use equal sign).
My golang skills are quite minimal (I did a quick turotial and added this PR) so please let me know if you see any problem or something needs to be updated. |
…ion subscription is returned.
"pending confirmation" such as "PendingConfirmation", "Pending Confirmation" etc.
@packplusplus, thats what my intention was. Am I missing something to get this pulled? |
/me is embarrassed At the time I searched and didn't see a PR (I commented on the fork not the pr directly). |
@jen20, What is the usual turn around time for PRs? |
Guys any update on this? |
Hi @srikalyan Can you provide any public examples of services which provide the auto-confirmation? I was hoping that Slack would be able to do this, but apparently not. 😢 From what I've read the SNS subscription confirmation works in a way that it requires the other end to call AWS API with a token that was sent to the provided HTTP(S) endpoint. This inherently means that the other end needs AWS access keys in order to call the API and confirm the subscription. These keys need to have the privilege to call Am I right? |
Hello @radeksimko, There are quite a few public services that auto confirm subscription for e.g. Pagerduty. Cloud watch events can be sent via SNS topic to Pagerduty service which can call proper members. As far as I can tell, we third party don't need AWS access keys and I definitely tested it with Pagerduty. Hope I've answered your questions and please let me know if need anything else. |
I see, thanks for the example, that's very helpful. I searched thru AWS Docs again to find more details about this and found this page: I think we should add a link to the docs and probably also mention PagerDuty as an example e.g.:
I will give this a full review in couple of days. |
…ields added in the PR and add the link to amazon describing the auto confirming subscription.
I've updated the documentation as per your suggestion. Please let me know if you have any more suggestions for this PR. |
"endpoint_auto_confirms": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
ForceNew: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe ForceNew: false
is a default behaviour so we shouldn't need to specify it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which applies to the other 2 fields below too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point but almost all the schema elements have ForceNew: false, I guess they made a bad copy :). I will fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not everything you see elsewhere in the codebase is worth copying, yet many things do! 😃
It is probably impossible to write a reliable acceptance test for this, unless we just hardcode a PagerDuty URL which would be generated manually I assume, so I won't insist on having one. 😃 I tried testing this manually with the following simple config: resource "aws_sns_topic" "user_updates" {
name = "cw-sns-topic"
}
resource "aws_sns_topic_subscription" "user_updates_sqs_target" {
topic_arn = "${aws_sns_topic.user_updates.arn}"
protocol = "https"
endpoint_auto_confirms = true
endpoint = "https://events.pagerduty.com/adapter/cloudwatch_sns/v1/*REDACTED*"
} and in my first attempt Terraform crashed, here's the interesting part of the crash log:
it looks like there was no ARN returned in the response from API. on my second attempt I just hit timeout (I assume because PagerDuty didn't confirm the subscription in 3 secs):
One way to get around the timeout issue is to use the Would you mind making the modifications I mentioned? |
Yeah np. I will make them asap. One question though, what did you mean when you said terraform crashed? Did you had any extra setting or is there a way that I can reproduce? Thanks for helping me out :). |
Nope, no special settings, if there is nil-dereference, Terraform just crashes and prints out the stack trace. In terms of reproduction I guess it may be tricky with the AWS API... if sometimes it returns A and minutes after it returns B. 😞 I guess you'll have to either rerun an example couple of times until you hit the problem or just trust my crash log above. |
1. Used resource.Retry instead of custom solution 2. Removed unnecessary variables and added required variable to resource.Retry.
I've made almost all the changes you have suggested except protocol contains check (as you have suggested it as optional ;). Also, I've tested it several times and could not reproduce the error stack trace :(. Just curios though, what go version are you using? I will keep an eye on it but It seems ok for now. |
Thanks, this looks much better on the first sight! I will give it another look during the weekend or next week. |
Thanks @radeksimko for all your help :). |
@@ -178,6 +187,12 @@ func subscribeToSNSTopic(d *schema.ResourceData, snsconn *sns.SNS) (output *sns. | |||
protocol := d.Get("protocol").(string) | |||
endpoint := d.Get("endpoint").(string) | |||
topic_arn := d.Get("topic_arn").(string) | |||
endpoint_auto_confirms := d.Get("endpoint_auto_confirms").(bool) | |||
confirmation_timeout_in_minutes := time.Duration(d.Get("confirmation_timeout_in_minutes").(int)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason for the time.Duration
wrapper here? I think that keeping it as integer should be ok.
It has no functional effect as I see you're actually multiplying this variable below with time.Minutes
, but the default representation of time.Duration
are nanoseconds which makes the variable name wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I don't convert it then I get the follow error
mismatched types time.Duration and int
On the other hand, I see your concern that the variable does not make sense
I will change it to
confirmation_timeout_in_minutes := d.Get("confirmation_timeout_in_minutes").(int)
and use time.Duration(int(time.Minute) * confirmation_timeout_in_minutes)
I have few other options too but I think this makes most sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will change it to
confirmation_timeout_in_minutes := d.Get("confirmation_timeout_in_minutes").(int)
and use time.Duration(int(time.Minute) * confirmation_timeout_in_minutes)
That's exactly what I had in mind. 👍
Besides one nitpick about code readability I'd be happy to merge this. I tried rerunning my previous example and it worked aok. Thanks for making all the modifications. |
Added support for http/https endpoints that auto confirms SNS topic subscription.
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
Added support for http/https endpoints that auto confirms SNS topic subscription.
http and https SNS topic subscription endpoints require confirmation to set a valid arn otherwise
arn would be set to "pending confirmation". If the endpoints auto confirm then arn is set
asynchronously but if we try to create another subscription with same parameters then api returns
"pending subscription" as arn but does not create another a duplicate subscription. In order to
solve this we should be fetching the subscription list for the topic and identify the subscription
with same parameters i.e., protocol, topic_arn, endpoint and extract the subscription arn.
Following changes were made to support the http/https endpoints that auto confirms
Added 3 extra parameters i.e.,
With these parameters help added support http and https protocol based endpoints that auto confirm.
Update website doc appropriately