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

Fixes for ignore_changes with unintended provider behavior #27141

Merged
merged 3 commits into from
Dec 4, 2020

Conversation

jbardin
Copy link
Member

@jbardin jbardin commented Dec 4, 2020

This covers 3 separate, but related issues that are interacting badly with ignore_changes and legacy providers.

The first is a more straightforward bug, where multiple entries for map keys in ignore_changes could cause cty.Transform to return early, leaving some values unchanged. Refactor the function to try and separate the fast-path a little better, and hopefully make it easier to follow.

The second is a side effect of some incorrect provider behavior, but we need to work with it to remain compatible with the legacy SDK. Because we allow legacy providers to depart from the contract and return changes to non-computed values, the plan response may have altered values that were already suppressed with ignore_changes. A prime example of this is where providers attempt to obfuscate config data by turning the config value into a hash and storing the hash value in the state. There are enough cases of this in existing providers that we must accommodate the behavior for now, so for ignore_changes to work at all on these values we re-apply ignore_changes to the planned state.

The effect of this will be limited by the LegacyTypeSystem flag, so as not to introduce more unintended ignore_changes behavior with new providers. The primary use case above won't be able to happen with providers using a new SDK, because returning a non-conforming plan will be an error.

The third issue concerns the use of the ignore_changes = all option, which when applied to the configuration will currently cause computed values to be populated into the temporary config value. This isn't a problem when generating the plan, but does effect providers' validation, as the legacy provider schema will reject these values. We can work around this by validating the original config before applying ignore_changes.

(In the future it we should probably have a way for processIgnoreChanges to skip computed values based on the schema. Since we also want a way to more easily query the schema for "computed-ness" to statically validate the ignore_changes arguments, we can fix these at the same time in a future change. This will most likely require some sort of method to retrieve info from the configschema.Block via a cty.Path, which we cannot easily do right now.)

Fixes #27106
Fixes #27103
Fixes #27097

The cty.Transform for ignore_changes could return early when building a
map that had multiple ignored keys.

Refactor the function to try and separate the fast-path a little better,
and hopefully make it easier to follow.
Because we allow legacy providers to depart from the contract and return
changes to non-computed values, the plan response may have altered
values that were already suppressed with ignore_changes. A prime example
of this is where providers attempt to obfuscate config data by turning
the config value into a hash and storing the hash value in the state.
There are enough cases of this in existing providers that we must
accommodate the behavior for now, so for ignore_changes to work at all
on these values, we will revert the ignored values once more on the
planned state.
The ignore_changes option `all` can cause computed attributes to show up
in the validation configuration, which will be rejected by the provider
SDK. Validate the config before applying the ignore_changes options.

In the future it we should probably have a way for processIgnoreChanges
to skip computed values based on the schema. Since we also want a way to
more easily query the schema for "computed-ness" to validate the
ignore_changes arguments for computed values, we can fix these at the
same time with a future change to configschema. This will most likely
require some sort of method to retrieve info from the configschema.Block
via cty.Path, which we cannot easily do right now.
@jbardin jbardin requested a review from a team December 4, 2020 13:48
@codecov
Copy link

codecov bot commented Dec 4, 2020

Codecov Report

Merging #27141 (4f4e8c1) into master (2c2ed53) will increase coverage by 0.03%.
The diff coverage is 88.88%.

Impacted Files Coverage Δ
terraform/eval_diff.go 69.36% <88.88%> (+2.85%) ⬆️
terraform/eval_apply.go 73.87% <0.00%> (+0.60%) ⬆️
dag/marshal.go 63.49% <0.00%> (+1.58%) ⬆️
terraform/node_resource_plan.go 98.05% <0.00%> (+1.94%) ⬆️

Copy link
Contributor

@mildwonkey mildwonkey left a comment

Choose a reason for hiding this comment

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

You're always good at this, but can I just say this PR has exceptionally good comments, thank you 🎉

// Because we allow legacy providers to depart from the contract and
// return changes to non-computed values, the plan response may have
// altered values that were already suppressed with ignore_changes.
// A prime example of this is where providers attempt to obfuscate
Copy link
Contributor

Choose a reason for hiding this comment

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

thank you for providing a "good" example in the comments, this is really helpful

@ghost
Copy link

ghost commented Jan 4, 2021

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked as resolved and limited conversation to collaborators Jan 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants