pulumi/pkg/resource/deploy
Will Jones 2aad59df18
Spot skipped-create dependencies even when inputs don't change (#17633)
`Create`s happen in response to new resources being present in a Pulumi
program but not in Pulumi's state snapshot. For instance, take the
following TypeScript program:

```typescript
const b = new Resource("b", { x: 2 })
const c = new Resource("c", { x: 3 }, { deletedWith: b })
```

When asked to run this program on an empty state with no arguments,
Pulumi will issue two `Create` calls -- one for `b`, and one for `c`.
The call for `c` will *depend on* `b`'s due to the need for
`deletedWith` to refer to `b`'s URN.

If instead of passing no arguments we ask Pulumi to perform a *targeted*
operation that *only targets `c`*, Pulumi will throw an error and refuse
to execute the program. This is because `c`'s `Create` would depend on
`b`'s `Create`, but since `b` has not been targeted, its `Create` will
not happen and thus `c`'s call cannot be built. Internally, we call
`b`'s omission a "skipped create", and keep track of these so that we
can trigger the error above appropriately.

So far, so good. Now, consider that we have executed the above program
with no targets, so that Pulumi's state contains both `b` and `c`, with
`c` depending on `b` via a `deletedWith` link. We now add the missing
`a` to the program and modify `b` to depend on it:

```typescript
const a = new Resource("a", { x: 1 })
const b = new Resource("b", { x: 2 }, { deletedWith: a })
const c = new Resource("c", { x: 3 }, { deletedWith: b })
```

If we were to run the program with no targets, we would expect a state
in which all of `a`, `b` and `c` existed. `c` would depend on `b` (as it
did before) and `b` would have a new dependency on `a`. Lovely.

Of course, we are not about to run the program with no targets. We are
instead interested in *targeting `b` only*. When we do, the following
sequence of events will unfold:

* `a`, not existing in the state already and not being targeted, will
yield a skipped create.
* `b` depends on a skipped create. However, its *inputs* have not
changed (`x` was `2` before, and it's still `2` after). Consequently,
`b` will have yielded a `SameStep`. We *incorrectly* assume this means
that skipped creates are not a problem (`SameStep`s mean no changes,
right?) and allow the deployment to proceed.
* We write the new `b` to the state, with a dependency on the skipped
create, yielding a snapshot integrity error.
* 💥

We might ask "why assume that `SameStep`s are safe?". From looking at
the existing test cases, it seems likely that this was designed to cover
the case where a skipped create is depended on *by another skipped
create* (which is internally represented as a `SameStep`) -- in such
cases, we don't need to error and the deployment can proceed. However,
this bug shows that there are cases where `SameStep` does not imply
skipped create. This commit thus tightens up the logic appropriately,
checking explicitly for `SameStep`s whose `IsSkippedCreate` method
returns true.
2024-10-30 16:17:30 +00:00
..
deploytest Have `Host.Provider` accept a `PackageDescriptor` (#17244) 2024-09-12 13:17:30 +00:00
providers Have `Host.Provider` accept a `PackageDescriptor` (#17244) 2024-09-12 13:17:30 +00:00
builtins.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
builtins_test.go Normalize plugin.Provider methods to (Context, Request) -> (Response, error) (#16302) 2024-06-07 19:47:49 +00:00
deployment.go Remove unused deployment option (#17559) 2024-10-16 08:54:32 +00:00
deployment_executor.go Centralize resource state dependency traversal (#17320) 2024-09-23 08:37:34 +00:00
deployment_executor_test.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
deployment_test.go Introduce snapshot metadata (#17430) 2024-09-30 16:45:40 +00:00
doc.go Document Go packages (#6009) 2021-01-11 11:07:59 -07:00
import.go Extend the TestReplacementParameterizedProvider test (#16644) 2024-07-15 08:33:36 +00:00
import_test.go Have `Host.Provider` accept a `PackageDescriptor` (#17244) 2024-09-12 13:17:30 +00:00
manifest.go Split Manifest type to it's own file (#8712) 2022-01-10 12:25:24 +00:00
manifest_test.go Refactor: move plugin kind to apitype (#15946) 2024-04-25 17:30:30 +00:00
plan.go Enable goheader rule and add missing license headers (#15473) 2024-09-09 12:05:45 +00:00
plan_test.go [ci] `pkg/resource/deploy` coverage (#14831) 2023-12-19 16:14:40 +00:00
snapshot.go Return pruned resources from `Snapshot.Prune` (#17454) 2024-10-02 12:14:40 +00:00
snapshot_test.go Fix flake in TestSnapshotPrune_FixesDanglingReferences (#17492) 2024-10-07 08:55:16 +00:00
source.go allow component providers to return more detailed error messages (#17306) 2024-09-25 15:38:36 +00:00
source_error.go Clean up deployment options (#16357) 2024-06-11 13:37:57 +00:00
source_error_test.go Clean up deployment options (#16357) 2024-06-11 13:37:57 +00:00
source_eval.go send a value to the abortchan instead of closing it (#17439) 2024-10-01 12:41:29 +00:00
source_eval_test.go send a value to the abortchan instead of closing it (#17439) 2024-10-01 12:41:29 +00:00
source_null.go Clean up deployment options (#16357) 2024-06-11 13:37:57 +00:00
source_query.go allow component providers to return more detailed error messages (#17306) 2024-09-25 15:38:36 +00:00
source_query_test.go allow component providers to return more detailed error messages (#17306) 2024-09-25 15:38:36 +00:00
state_builder.go Revert "Revert "Run integration tests and dev builds with race detection" (#15998)" (#16148) 2024-05-09 16:15:41 +00:00
state_builder_test.go When changing parents also fix URNs (#13935) 2023-09-14 19:52:27 +00:00
step.go Enable some more linting rules (#17456) 2024-10-03 17:37:13 +00:00
step_executor.go Use int32 in Go interfaces that map to protobufs using int32 (#17068) 2024-08-28 13:45:17 +00:00
step_executor_test.go Clean up deployment options (#16357) 2024-06-11 13:37:57 +00:00
step_generator.go Spot skipped-create dependencies even when inputs don't change (#17633) 2024-10-30 16:17:30 +00:00
step_generator_test.go Enable some more linting rules (#17456) 2024-10-03 17:37:13 +00:00
step_test.go Add input keys from diff during import step to warning and error message (#17312) 2024-09-25 13:21:50 +00:00
target.go Add tokens.StackName (#14487) 2023-11-15 07:44:54 +00:00
target_test.go upgrade to latest version of golangci-lint (#15977) 2024-04-19 06:20:33 +00:00