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

Non-idempotent SNS topic creation workaround #3235

Merged
merged 7 commits into from Jan 16, 2024

Conversation

VenelinMartinov
Copy link
Contributor

@VenelinMartinov VenelinMartinov commented Jan 8, 2024

This addresses #2009.

Previously the creation of an SNS topic was idempotent, so you could create multiple pulumi resources corresponding to the same SNS topic, causing confusing behaviour when one was deleted/replaced.

With this PR, trying to create a topic which exists will error.

Note that this is kind of a breaking change - pulumi programs where the same SNS topic was created through multiple pulumi resources would run fine before but will now error.

Note also the mutex around the listing and creating of SNS topics - this is needed to prevent race conditions within the same program. Race conditions with other programs are still possible and that is unavoidable because of the AWS API.

@t0yv0
Copy link
Member

t0yv0 commented Jan 8, 2024

What does TF do in this case? Does TF have the same problem? If so is there an upstream ticket ref?

Does this solve updates as well or only creates?

@t0yv0
Copy link
Member

t0yv0 commented Jan 8, 2024

Actually reading the original ticket, it sounds like this fix will make it fail loudly, which is slightly better than current silent corruption behavior but still not ideal? To confirm is that what we're going for?

// Some partitions (e.g. ISO) may not support tag-on-create.
@@ -291,6 +322,7 @@ func resourceTopicCreate(ctx context.Context, d *schema.ResourceData, meta inter

output, err = conn.CreateTopic(ctx, input)
Copy link
Member

Choose a reason for hiding this comment

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

What does conn.CreateTopic return if the topic already exists?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is what the docs say:

This action is idempotent, so if the requester already owns a topic with the specified name, that topic's ARN is returned without creating a new topic.

And in my testing that seems to indeed be the behaviour.

Copy link
Member

Choose a reason for hiding this comment

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

Will we need to change the docs since we have changed the behavior of the resource?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Neither our docs nor terraforms mention anything about the create returning existing resources:
https://www.pulumi.com/registry/packages/aws/api-docs/sns/topic/
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic

Given that the new behaviour is the default behaviour for pulumi resources, I'd say this does not warrant any additional documentation, LMK if you disagree

@VenelinMartinov
Copy link
Contributor Author

Yeah, exactly - this change will make the creation of a second SNS topic with the same name fail, instead of the current behaviour of silently passing and creating weirdness down the line.

patches/0037-Non-idempotent-sns-topic-creation.patch Outdated Show resolved Hide resolved
patches/0037-Non-idempotent-sns-topic-creation.patch Outdated Show resolved Hide resolved
// Some partitions (e.g. ISO) may not support tag-on-create.
@@ -291,6 +322,7 @@ func resourceTopicCreate(ctx context.Context, d *schema.ResourceData, meta inter

output, err = conn.CreateTopic(ctx, input)
Copy link
Member

Choose a reason for hiding this comment

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

Will we need to change the docs since we have changed the behavior of the resource?

@VenelinMartinov
Copy link
Contributor Author

VenelinMartinov commented Jan 9, 2024

This is the upstream issue: hashicorp/terraform-provider-aws#6245

Note it's closed but not completed.

Copy link

github-actions bot commented Jan 9, 2024

Does the PR have any schema changes?

Does the PR have any schema changes?

Looking good! No breaking changes found.
No new resources/functions.

Maintainer note: consult the runbook for dealing with any breaking changes.

@t0yv0
Copy link
Member

t0yv0 commented Jan 9, 2024

I'm a little wary of cost-benefit of this PR since upstream didn't fix it we're introducing a bit of slowdown and failure mode for creating the topic, but if we do it right (without slowing down for clients with 1000 topics) I think on balance the fact that it's an upvoted request both in our repo and upstream - let's try it! Thank you!

+ return diag.Errorf("SNS Topic (%s) already exists", name)
+ }
+ if !tfresource.NotFound(err) {
+ return diag.FromErr(err)
Copy link
Member

Choose a reason for hiding this comment

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

Could go both ways here, logging or erroring out. I guess erroring out is reasonable, though it introduces a new failure path.

Copy link
Member

Choose a reason for hiding this comment

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

Unless AWS changes its URN scheme, it is wrong to create two of these. I agree that we should error here.

Copy link
Member

@t0yv0 t0yv0 left a comment

Choose a reason for hiding this comment

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

Thank you! :shipit:

Copy link
Member

@iwahbe iwahbe left a comment

Choose a reason for hiding this comment

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

LGTM.

I would love to see an ideation doc presenting this strategy as a possible solution for structural resources. My suspicion is that we can determine the "name" (ARN for AWS) for most structural resources.

}
}

+func constructTopicArn(client *sns.Client, account, region, snsTopicName string) string {
Copy link
Member

Choose a reason for hiding this comment

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

This is a much cleaner implementation.

+ return diag.Errorf("SNS Topic (%s) already exists", name)
+ }
+ if !tfresource.NotFound(err) {
+ return diag.FromErr(err)
Copy link
Member

Choose a reason for hiding this comment

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

Unless AWS changes its URN scheme, it is wrong to create two of these. I agree that we should error here.

@VenelinMartinov
Copy link
Contributor Author

VenelinMartinov commented Jan 16, 2024

pulumi/pulumi#9925 looks like the exact issue this fixes - Fraser noted they are related there. Might be worth lifting the logic into the bridge since there's a few of these resources.

I'll merge this and then raise this as a workaround for idempotent creates.

Edit: thinking about this a bit more, it might be a bit difficult to lift in the bridge, since there'd be a lot of specific logic for determining the logical name of the resource - our reads prob work off the URN, which would not be the same in this case.

@VenelinMartinov VenelinMartinov merged commit 976def3 into master Jan 16, 2024
18 checks passed
@VenelinMartinov VenelinMartinov deleted the vvm/sns_nonidempotent_create_workaround branch January 16, 2024 18:46
@iwahbe
Copy link
Member

iwahbe commented Jan 16, 2024

pulumi/pulumi#9925 looks like the exact issue this fixes - Fraser noted they are related there. Might be worth lifting the logic into the bridge since there's a few of these resources.

I'll merge this and then raise this as a workaround for idempotent creates.

Edit: thinking about this a bit more, it might be a bit difficult to lift in the bridge, since there'd be a lot of specific logic for determining the logical name of the resource - our reads prob work off the URN, which would not be the same in this case.

We would be calling TFs read in the case of the bridge, not Pulumi's. In essence, we would ask TF to "import" the resource, and if the import succeeds, we would then fail.

VenelinMartinov added a commit that referenced this pull request Jan 17, 2024
VenelinMartinov added a commit that referenced this pull request Jan 17, 2024
This reverts commit 976def3.

Until we sort out
#3268 (comment)

It hasn't been released so no need to patch it.
corymhall added a commit that referenced this pull request Apr 10, 2024
This is a re-roll of #3235.

See [this comment](#3288 (comment))
for why we are re-rolling this.

closes #3288

Co-authored-by: VenelinMartinov <venelin.v.martinov@gmail.com>
corymhall added a commit that referenced this pull request Apr 11, 2024
This is a re-roll of #3235.

See this comment for why we are re-rolling this.

closes #3288

Co-authored-by: VenelinMartinov venelin.v.martinov@gmail.com
corymhall added a commit that referenced this pull request Apr 12, 2024
This is a re-roll of #3235.

See [this
comment](#3288 (comment))
for why we are re-rolling this.


Previously the creation of an SNS topic was idempotent, so you could
create multiple pulumi resources corresponding to the same SNS topic,
causing confusing behaviour when one was deleted/replaced.

With this PR, trying to create a topic which exists will error.

Note that this is kind of a breaking change - pulumi programs where the
same SNS topic was created through multiple pulumi resources would run
fine before but will now error.

Note also the mutex around the listing and creating of SNS topics - this
is needed to prevent race conditions within the same program. Race
conditions with other programs are still possible and that is
unavoidable because of the AWS API.

fixes #3288, fixes #2009.

Co-authored-by: VenelinMartinov venelin.v.martinov@gmail.com
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants