pulumi/pkg/engine/lifecycletest/testdata/output/TestPendingReplaceFailureDo.../0
Will Jones ba43cb6fc7
Don't set `PendingReplacement` until `Delete` succeeds (#16699)
There are a number of use cases for `Delete` steps in a Pulumi
operation. Aside from direct deletions, where a resource has been
removed from a program, they are also a key component of _replacements_,
whereby a resource has changed in a manner where it cannot simply be
updated in the provider but instead must be completely removed and
reconstructed. In such cases, Pulumi offers two options:

* "Delete after replace", in which a new resource is first created
before the old one is deleted.
* "Delete before replace", in which the old resource is first deleted
before a replacement is created.

Delete-after-replace is the default, since where possible it is
typically the preferred option by users, enabling e.g. zero-downtime
deployments. However, there are cases where delete-after-replace is not
possible (e.g. because the new and old resources would clash in some
manner), and so delete-before-replace is an option that can be opted
into.

In cases where the deletion must happen first, we must be careful how we
handle the Pulumi state. Either or both of the delete and create calls
could fail, and we always want a state file that tells us how to resume
a failed call to yield the desired outcome. In the case of
delete-before-replace operations, a key component of resumable state is
the `PendingReplacement` field on a resource. `PendingReplacement`
indicates that a resource has been deleted in the provider, but that
this deletion is part of a replacement (and thus that a create call will
subsequently occur). In this way, the deleted resource can remain in the
state file throughout the operation, meaning that e.g. resources that
depend on the deleted resource won't have their dependencies violated
(causing a snapshot integrity error).

Alas, until this point, `PendingReplacement` was set unconditionally on
the creation of a delete-before-replace step, meaning that if the
provider delete failed, we'd elide the delete on a retry and end up with
a bad state failing snapshot integrity checks. This commit fixes this by
moving the setting of `PendingReplacement` inside `DeleteStep.Apply`, so
that it occurs only if the provider delete call succeeds. It also adds a
lifecycle test to test this case and hopefully guard against
regressions.

Fixes #16597
Part of #16667
2024-07-18 12:27:06 +00:00
..
diff.stderr.txt Don't set `PendingReplacement` until `Delete` succeeds (#16699) 2024-07-18 12:27:06 +00:00
diff.stdout.txt Don't set `PendingReplacement` until `Delete` succeeds (#16699) 2024-07-18 12:27:06 +00:00
eventstream.json Don't set `PendingReplacement` until `Delete` succeeds (#16699) 2024-07-18 12:27:06 +00:00
progress.stderr.txt Don't set `PendingReplacement` until `Delete` succeeds (#16699) 2024-07-18 12:27:06 +00:00
progress.stdout.txt Don't set `PendingReplacement` until `Delete` succeeds (#16699) 2024-07-18 12:27:06 +00:00