Skip to content
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

Fix SNS subscription sub/unsub/sub bug. #1480

Merged
merged 1 commit into from
Aug 29, 2017
Merged

Fix SNS subscription sub/unsub/sub bug. #1480

merged 1 commit into from
Aug 29, 2017

Conversation

handlerbot
Copy link
Contributor

@handlerbot handlerbot commented Aug 23, 2017

The Terraform SNS subscriptions implementation has a bug where it:

  • creates a new subscription
  • verifies the subscription as created
  • evaluates the newly created subscription object
  • sees that some of the fields of the object have "changed" (this is technically correct, strings have changed from their initial empty value of "" to the values configured by the Terraform configuration)
  • decides that the subscription configuration has been "updated"
  • destroys the subscription and recreates it!

I noticed this when implementing SNS subscription auto-confirmation in our servers; when I created a new SNS subscription via Terraform, my server got two SNS subscription confirmation requests when I only expected one.

With TF_LOG=debug, the AWS provider at HEAD shows these outgoing requests:

[DEBUG] [aws-sdk-go] DEBUG: Request sns/Subscribe Details:
[DEBUG] [aws-sdk-go] DEBUG: Request sns/ListSubscriptionsByTopic Details:
[DEBUG] [aws-sdk-go] DEBUG: Request sns/Unsubscribe Details:
[DEBUG] [aws-sdk-go] DEBUG: Request sns/Subscribe Details:
[DEBUG] [aws-sdk-go] DEBUG: Request sns/ListSubscriptionsByTopic Details:
[DEBUG] [aws-sdk-go] DEBUG: Request sns/GetSubscriptionAttributes Details:  

I instrumented the AWS provider to show what it thought was happening with the protocol, endpoint, and topic_arn fields:

[DEBUG] protocol original , new https
[DEBUG] endpoint original , new https://<mydomain>/<myurl>
[DEBUG] topic_arn original , new arn:aws:sns:<region>:<account_id>:<topic_name>

With my PR, these are the outgoing requests I see:

[DEBUG] [aws-sdk-go] DEBUG: Request sns/Subscribe Details:
[DEBUG] [aws-sdk-go] DEBUG: Request sns/ListSubscriptionsByTopic Details:
[DEBUG] [aws-sdk-go] DEBUG: Request sns/ListSubscriptionsByTopic Details:
[DEBUG] [aws-sdk-go] DEBUG: Request sns/GetSubscriptionAttributes Details:

It's arguable that something like wasSetAndHasChange belongs upstream in https://github.com/hashicorp/terraform/blob/master/helper/schema/resource_data.go but I'd rather get this fixed here first, and then we can assess whether that is worth trying to uplift to main Terraform.

Copy link
Member

@radeksimko radeksimko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch! This looks like a reasonable bugfix - I just left you one comment about simplicity.

I'm assuming we can't test the bugfix as the difference between old/new behaviour is only visible from log?

if d.HasChange("protocol") || d.HasChange("endpoint") || d.HasChange("topic_arn") {
// If any changes happened, un-subscribe and re-subscribe.
// We also have to handle the "freshly-created subscription" case, where all of the fields have "changed", but only from their original value of empty strings ("").
if wasSetAndHasChange(d, "protocol") || wasSetAndHasChange(d, "endpoint") || wasSetAndHasChange(d, "topic_arn") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can avoid adding the wrapper function and use d.IsNewResource() instead here.

e.g.

if !d.IsNewResource() && (d.HasChange("protocol") || d.HasChange("endpoint") || d.HasChange("topic_arn")) {

@radeksimko radeksimko added bug Addresses a defect in current functionality. waiting-response Maintainers are waiting on response from community or contributor. labels Aug 23, 2017
@handlerbot
Copy link
Contributor Author

@radeksimko Thx for getting back so quick. :-) Revised as requested, and TY for the suggestion; I don't know the schema object functions well enough to have known about IsNewResource() yet...

Re: tests, I've tested it live in my AWS development environment multiple times, including the revised change, and it does the right thing. The existing tests for the module didn't pick this up because it only tests for successful creation of the resource at the end of complete execution, and the create/destroy/create bug does result in successful creation, except with a little extra work in the middle. The testing framework does not look conducive to adding a test to prevent against this recurring without a bunch of refactoring, and I bet this kind of bug is a (potentially) widespread issue in the AWS provider...

@radeksimko radeksimko removed the waiting-response Maintainers are waiting on response from community or contributor. label Aug 29, 2017
Copy link
Member

@radeksimko radeksimko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for making the requested change.

I bet this kind of bug is a (potentially) widespread issue in the AWS provider...

I'm not sure if I understand correctly what do you mean by "this kind of bug" in a wider context. 🤔

Almost each service API often works differently in AWS and I think SNS is fairly unique with its (potentially destructive) "Subscribe/Unsubscribe" method.

Some other resources/APIs have Put* (which cover both create & update), some have Ensure*, some Update* and in most of these cases it's quite harmless to call such methods during both updates & creation.

Please do let us know if you're aware of similar bugs in other resources by submitting new issues. Thanks.

@radeksimko radeksimko merged commit ad79d53 into hashicorp:master Aug 29, 2017
@stevehorsfield
Copy link
Contributor

👍

@handlerbot handlerbot deleted the sns-sub-resub branch September 14, 2017 00:29
nbaztec pushed a commit to nbaztec/terraform-provider-aws that referenced this pull request Sep 26, 2017
Fix SNS subscription sub/unsub/sub bug.
@ghost
Copy link

ghost commented Apr 11, 2020

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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Apr 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Addresses a defect in current functionality.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants