For a dynamic resource, is it possible to prevent ...
# general
w
For a dynamic resource, is it possible to prevent a replace operation when the provider (__provider) changes? We are using the dynamic resource tool to create SNS topic subscriptions in AWS, and do not want users to be resubscribed whenever the provider changes e.g. when we upgrade dependencies like pulumi-aws, etc. cc @dazzling-memory-8548
@gentle-diamond-70147 @white-balloon-205 any thoughts on this?
g
Can you post the detailed diff (e.g.
preview --diff
) from when you upgrade a dependency and it wants to do the replace?
w
Copy code
+-pulumi-nodejs:dynamic:Resource: (replace)
        [id=arn:aws:sns:us-west-2:279673228106:monitoring:167c2e12-d9c7-495e-a5f6-2a7f4b2a66ab]
        [urn=urn:pulumi:dev1::ucboitlake::pulumi-nodejs:dynamic:Resource::monitoring-topic-email-subscription]
        email     : "<mailto:dustin.farris@colorado.edu|dustin.farris@colorado.edu>"
        region    : "us-west-2"
        topicArn  : "arn:aws:sns:us-west-2:279673228106:monitoring"
Resources:
    +-1 to replace
    50 unchanged
I got this by just npm linking the dependent (internal) library that contains the definition for the dynamic resource — haven't actually upgraded anything yet — but either way, we want to avoid a replace action here since the inputs to this resource have not changed.
w
Have you tried
ignoreChanges: [“__provider”]
yet? That might work. That said, I’m surprised this is triggering a replace in the first place unless your provider itself is written in such a way that it is requesting this. Would love a bug report with a repro if you are seeing this replace on latest versions.
w
ok i'm working on reproducing — if i get anywhere meaningful i'll submit a bug
it looks like this may have been a bug in our code where i was not exporting an
out
in create that was getting compared to in the diff callback — fixing that, it looks like changes to __provider do trigger an "update" operation but it does not call the create/delete (replace) callbacks. I assume that means __provider "update"s are strictly internal to the stack? Is that correct/expected?
the last push wiped out all of my outs from the stack
only __provider is there
w
I assume that means __provider "update"s are strictly internal to the stack? Is that correct/expected?
Well - you should still see the provider
Update
method be called which can have an impact if there are actually changes. But yes - it should be possible for
__provider
to change and for that to not otherwise impact your dynamic resource.
the last push wiped out all of my outs from the stack
That is very surprising - though depends on a lot on your dynamic provider - since dynamic providers have a lot of control over how state is managed. Do make sure that your
Create
and
Update
implementations return all the state you want to manage for all the cases your provider can support.
w
i have not defined an
update
callback — possible that its absence caused an empty outs?
(for context: AWS SNS Subscriptions can't be updated once created)
w
I think the typical approach would be that either you implement
update
, or you ensure that your
diff
will only ever replace. If you have a pattern you are trying to use, and are seeing surprising results that don't feel right - definitely do open an issue and one of the folks who works more deeply in this space can take a look.
w
ok, if i’m reading the docs right,
changes
defaults to
true
from diff, so it sounds like i need to set that to
false
, and then set
replaces
for things that actually do warrant change
I think I've figured this out: to recap I have a diff that looks like this:
☝️ I had a bug in my code where I was not returning
topicArn
as an output in the
create
callback. Therefore, any time
diff
was called, a "replace" operation was ordered. This only seemed to happen when the __provider changed though. I am inferring from this that pulumi does its own inspection of old inputs in the stack vs. new inputs in the program configuration — and only consults
diff
if it sees that something has changed. Fixing that, it now seems that any time
__provider
changes,
update
implicitly gets triggered. I did not have an
update
callback defined since this AWS resource cannot be updated once created. This had the undesirable side-effect of wiping all of my outputs whenever __provider updated. I added the following callback:
Copy code
async update(id, { email, topicArn, region }) {
        return { outs: { email, topicArn, region } };
    },
and all seems to be well now.