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

Consider rewriting makeDetailedDiff #1895

Closed
t0yv0 opened this issue Apr 22, 2024 · 6 comments · Fixed by #2405
Closed

Consider rewriting makeDetailedDiff #1895

t0yv0 opened this issue Apr 22, 2024 · 6 comments · Fixed by #2405
Assignees
Labels
kind/enhancement Improvements or new features resolution/fixed This issue was fixed

Comments

@t0yv0
Copy link
Member

t0yv0 commented Apr 22, 2024

Hello!

  • Vote on this issue by adding a 👍 reaction
  • If you want to implement this feature, comment to let us know (we'll work with you on design, scheduling, etc.)

Issue details

Consider rewriting makeDetailedDiff logic that populates detailedDiff.

Desired properties

  • when provider returns DIFF_SOME, it must also return a detailedDiff explaining why the changes are happening
  • when provider returns DIFF_NONE, it must return no detailedDiff contradicting that
  • when the user specifies an ignoreChanges option, changes are suppressed and detailedDiff reflects that correctly

Why the current implementation cannot deliver the desired properties

This is elaborated in #1501 - essentially the current
implementation is trying to inspect a difficult to work with InstanceDiff object by doing 3 passes over news and olds
projection to TF. This works for the happy case but it does not faithfully hit the keys that may be changed by the TF
planning phase if they are not present in the union of Pulumi olds and news, and it creates confusion for changes
involving paths to set elements that are projected to Pulumi.

How can a new implementation look like

The suggested replacement is to compute the diff directly on Pulumi level (comparing PropertyValue representations of
resource state). Ideally this would take the exact same logic that Pulumi CLI uses to diff two PropertyValue instances
when the CLI is in charge of the diff completely.

What makes bridged providers special is that there is the underground phase of doing PlanResourceChange together with TF
that cannot be cleanly exposed to the engine in the current provider protocol. As a result bridged providers partially
take over the responsibility for the diffs and in particular detailed diffs and ignore changes.

This can still be made to work in the following way:

  1. as is already done, compute planned state (via PlanResourceChange); this phase should continue taking care of
    ignoreChanges at a semantic level

  2. translate this planned state back to the PropertyValue domain

  3. elaborate the difference between old state PropertyValue and the planned state PropertyValue at Pulumi level without
    any further reference to the underlying TF provider schema

This implementation will avoid working with InstanceDiff object, work entirely at Pulumi level and be WISYWIG-defensible at Pulumi level, and support ignoreChanges.

Downsides

Changs involving sets will still involve confusing reordering of list elements in the Pulumi projection. I believe there is no universally good way currently to surface set diffs without making changes to Pulumi CLI diff display to cooperate a little bit better when displaying these changes, although partial solutions may be possible - heuristics that improve a lot of common cases.

Issues

#1501
#186
#1245
#752
#1867
#1756

Affected area/feature

@t0yv0 t0yv0 added needs-triage Needs attention from the triage team kind/enhancement Improvements or new features labels Apr 22, 2024
@iwahbe iwahbe removed the needs-triage Needs attention from the triage team label Apr 22, 2024
This was referenced May 2, 2024
@VenelinMartinov
Copy link
Contributor

VenelinMartinov commented May 6, 2024

Note that a prerequisite here is rolling out PlanResourceChange - the proposed implementation will only take effect for resources under that

That could be an upside too - any changes here would already be flagged behind PlanResourceChange.

related: #1785


Linking in the plugin-sdk patch which we added in order to support PlanResourceChange: pulumi/terraform-plugin-sdk#35 - that was partly motivated by the way we do DetaileDiff in the bridge


We might also want to put in a bit of work in #1867 to be more confident in any changes we ship to detailedDiff - otherwise we'd likely be stuck with an unending resource-by-resource rollout.

@VenelinMartinov
Copy link
Contributor

@t0yv0 is this a duplicate of #1504? Either way, some useful context there too.

t0yv0 added a commit that referenced this issue May 6, 2024
With AWS 3880 there is some evidence (derivation in
#1917) that
sometimes TF has entries in the InstanceDiff.Attributes while still
planning to take the resource to the end-state that is identical to the
original state. IN these cases, TF does not display a diff but Pulumi
does.

The root cause here remains unfixed
(#1895) - Pulumi
bridge is editing terraform-pulgin-sdk to expose the InstanceDiff
structure to connect it to the makeDetailedDiff machinery. Pulumi
should, like TF, stick to the gRPC protocol and rely only on the
PlannedState value.

We can incrementally approach the desired behavior with this change
though which detects PlannedState=PriorState case and suppresses any
diffs in this case.

Fixes:

- pulumi/pulumi-aws#3880
- pulumi/pulumi-aws#3306
- pulumi/pulumi-aws#3190
- pulumi/pulumi-aws#3454

---------

Co-authored-by: Venelin <[email protected]>
@t0yv0
Copy link
Member Author

t0yv0 commented May 6, 2024

Actually indeed, looks like this one I wrote a bit later so it has my latest understanding but the ask is the same as in #1504. We should be able to write a much better detailedDiff now.

@VenelinMartinov
Copy link
Contributor

Note that the proposal here is not only for detailed diff - the same algorithm influences if we return DIFF_SOME or DIFF_NONE to the engine, so the name is a bit misleading.

changes := pulumirpc.DiffResponse_DIFF_NONE
if len(diff) > 0 || *forceDiff {
changes = pulumirpc.DiffResponse_DIFF_SOME
}

@t0yv0
Copy link
Member Author

t0yv0 commented May 8, 2024

It shouldn't influence result, indeed, once we're done here.

@mjeffryes mjeffryes modified the milestones: 0.108, 0.107 Jul 24, 2024
@mjeffryes mjeffryes removed this from the 0.108 milestone Aug 19, 2024
VenelinMartinov added a commit that referenced this issue Aug 20, 2024
This adds integration tests around detailed diff for string, list, set
and map attributes.

Quite a few issues with:
- Handling empty collections being removed/added - these are not shown
in most cases
- Adding/removing elements being duplicated in the detailed diff output
- Outright wrong diff for `set element removed middle` and `set element
added front` similar to
#2103

Opened follow-up issues:
- [Detailed diff empty collection diffs not
shown](#2233)
- [Detailed diff duplicated collection
diffs](#2234)
- [Detailed diff for set element changes shows more additions/removals
than
present](#2235)

Related to #1895
@pulumi-bot pulumi-bot added the resolution/fixed This issue was fixed label Oct 1, 2024
@pulumi-bot
Copy link
Contributor

This issue has been addressed in PR #2405 and shipped in release v3.92.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement Improvements or new features resolution/fixed This issue was fixed
Projects
None yet
5 participants