Commit Graph

199 Commits

Author SHA1 Message Date
Martin Atkins 7c6e78bcb0 plans: Track both the previous run and prior states in the plan
Until now we've not really cared much about the state snapshot produced
by the previous Terraform operation, except to use it as a jumping-off
point for our refresh step.

However, we'd like to be able to report to an end-user whenever Terraform
detects a change that occurred outside of Terraform, because that's often
helpful context for understanding why a plan contains changes that don't
seem to have corresponding changes in the configuration.

As part of reporting that we'll need to keep track of the state as it
was before we did any refreshing work, so we can then compare that against
the state after refreshing. To retain enough data to achieve that, the
existing Plan field State is now two fields: PrevRunState and PriorState.

This also includes a very shallow change in the core package to make it
populate something somewhat-reasonable into this field so that integration
tests can function reasonably. However, this shallow implementation isn't
really sufficient for real-world use of PrevRunState because we'll
actually need to update PrevRunState as part of planning in order to
incorporate the results of any provider-specific state upgrades to make
the PrevRunState objects compatible with the current provider schema, or
else our diffs won't be valid. This deeper awareness of PrevRunState in
Terraform Core will follow in a subsequent commit, prior to anything else
making use of Plan.PrevRunState.
2021-05-05 15:11:05 -07:00
Martin Atkins b802237e03 plans: Track an optional extra "reason" for some planned actions
Previously we were repeating some logic in the UI layer in order to
recover relevant additional context about a change to report to a user.
In order to help keep things consistent, and to have a clearer path for
adding more such things in the future, here we capture this user-facing
idea of an "action reason" within the plan model, and then use that
directly in order to decide how to describe the change to the user.

For the moment the "tainted" situation is the only one that gets a special
message, matching what we had before, but we can expand on this in future
in order to give better feedback about the other replace situations too.

This also preemptively includes the "replacing by request" reason, which
is currently not reachable but will be used in the near future as part of
implementing the -replace=... plan command line option to allow forcing
a particular object to be replaced.

So far we don't have any special reasons for anything other than replacing,
which makes sense because replacing is the only one that is in a sense
a special case of another action (Update), but this could expand to
other kinds of reasons in the future, such as explaining which of the
few different reasons a data source read might be deferred until the
apply step.
2021-04-29 17:50:46 -07:00
Martin Atkins c6a7d080d9 core: Generalize the idea of a "plan mode", vs just destroy flag
Previously there were only two planning modes: normal mode and destroy
mode. In that context it made sense for these to be distinguished only by
a boolean flag.

We're now getting ready to add our third mode, "refresh only". This
establishes the idea that planning can be done in one of a number of
mutually-exclusive "modes", which are related to but separate from the
various other options that serve as modifiers for the plan operation.

This commit only introduces the new plans.Mode type and replaces the
existing "destroy" flag with a variable of that type. This doesn't cause
any change in effective behavior because Terraform Core still supports
only NormalMode and DestroyMode, with NewContext rejecting an attempt to
create a RefreshMode context for now.

It is in retrospect a little odd that the "destroy" flag was part of
ContextOpts rather than just an argument to the Plan method, but
refactoring that would be too invasive a change for right now so we'll
leave this as a field of the context for now and save revisiting that for
another day.
2021-04-27 08:23:54 -07:00
Kristin Laemmert f6505870cc
Mildwonkey/providers interface renaming (#27805)
* providers.Interface: huge renamification

This commit renames a handful of functions in the providers.Interface to
match changes made in protocol v6. The following commit implements this
change across the rest of the codebase; I put this in a separate commit
for ease of reviewing and will squash these together when merging.

One noteworthy detail: protocol v6 removes the config from the
ValidateProviderConfigResponse, since it's never been used. I chose to
leave that in place in the interface until we deprecate support for
protocol v5 entirely.

Note that none of these changes impact current providers using protocol
v5; the protocol is unchanged. Only the translation layer between the
proto and terraform have changed.
2021-02-18 10:13:43 -05:00
James Bardin e4e50617aa add failing test, and start new test files
The existing context test files are becoming quite unwieldy.
Start new ones both to make editing easier, and to help discourage the
copy+pasting of older test patterns we no longer need.
2021-01-21 12:43:50 -05:00
James Bardin 68b65cc98a
Merge pull request #27512 from hashicorp/jbardin/output-plans
Create and Delete actions for output plans
2021-01-14 11:09:23 -05:00
James Bardin 191124e9c9 detect new outputs and plans as Create actions
Rather than using a prior value of null to indicate create, which is
imprecise because null is a valid output value, only plan values that
didn't exist in the prior state as Create changes.
2021-01-14 10:54:23 -05:00
James Bardin 57f004e0ef existing outputs can only be Updated
The planning logic here was inspired by resources, but unlike resources
a null value is valid for an output and does not necessarily indicate it
is being removed. If both before and after are null, the change should
be NoOp. When an output is removed from the configuration, we have a
separate node to create a Delete action to remove it from the state.
2021-01-14 08:59:31 -05:00
James Bardin e075c8ab8b remove unneeded testDiffFn and testApplyFn calls
Remove any calls to testDiffFn and testApplyFn which don't effect the
test result. This way we have more tests using predictable provider
behavior, which is more likely to uncover legitimate regressions as the
particular behavior of the legacy mock provider logic does not need to
be taken into account.
2021-01-13 17:36:32 -05:00
James Bardin 2e2c9e07e5 add default behavior to the MockProvider
Add reasonable default behavior to the mock provider, so that may do not
need to depend on the idiosyncrasies of the old (though updated) test
testDiffFn and to a lesser extend the testApplyFn. This behavior is
based directly upon the documented resource lifecycle, rather
than be an ad-hoc collection of behaviors from old tests.

As a proof of concept, remove all uses of testDiffFn from the plan
context tests that don't cause the tests to fail.
2021-01-12 17:47:55 -05:00
James Bardin 7dd570ef6c change mock provider to use GetSchemaResponse
This ensures that test providers are using the same types as actual
providers.
2021-01-12 16:31:18 -05:00
James Bardin 5fe848b642 change mock return values to pointers
This allows up to detect an unset value from the zero value so that
defaults can be implemented, while still allowing tests to return
specific values of their choosing.
2021-01-12 15:16:48 -05:00
Alisdair McDiarmid 1fa65bdd91 core: Fix sensitive value variable validation
Binding a sensitive value to a variable with custom validation rules
would cause a panic, as the validation expression carries the sensitive
mark when it is evaluated for truthiness. This commit drops the marks
before testing, which fixes the issue.
2021-01-05 13:52:33 -05:00
Pam Selle 87b576da7a Roll back test schema expansion and isolate
Isolate the test schema expansion, because having NestingSet
in the schema actually necessitates [] values in the AttrsJson.
While this didn't fail any tests on its addition, that
is scary and so isolate this to the one test using it.
2020-12-18 15:08:44 -05:00
James Bardin 1309b36b83 plan context test for mysterious changes
This plan would occasionally show changes when there weren't any due to
the sensitive marks being compared incorrectly.
2020-12-17 12:55:58 -05:00
James Bardin c85adf191a modify ProvidedBy to indicate no provider needed
Because of the composition pattern used within core, we can't easily
remove a behavior from an embedded type. Rather than trying to
re-implement all necessary methods on the
NodePlannableResourceInstnaceOrphan to exclude orphaned data resources
from GraphNodeProviderConsumer, we can modify ProvidedBy to indicate
when there is no provider required.
2020-12-17 09:01:20 -05:00
Pam Selle ae025248cc
Merge pull request #27131 from hashicorp/pselle/double-marks
Avoid double-marking variables
2020-12-04 13:21:54 -05:00
Pam Selle 12b5d437da Avoid double-marking variables
It is possible, say with multiple layers of
sensitive variables, to "double-mark" a variable.
Add a check to ensure this does not happen.
2020-12-04 13:10:02 -05:00
James Bardin 4f4e8c17e0 validate the configuration before ignore_changes
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.
2020-12-03 17:59:03 -05:00
James Bardin 02e7efab9e re-apply ignore_changes after plan for legacy
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.
2020-12-03 17:44:35 -05:00
James Bardin 1e8537b8d4 remove unused 2020-12-02 13:59:18 -05:00
James Bardin 8a325ea54b remove legacy provisioner types 2020-12-02 12:33:17 -05:00
James Bardin e7b2d98ca3 Use prepared config in provider.Configure
Core is only using the PrepareProviderConfig call for the validation
part of the method, but we should be re-validating the final config
immediately before Configure.

This change elects to not start using the PreparedConfig here, since
there is no useful reason for it at this point, and it would
introduce a functional difference between terraform releases that can be
avoided.
2020-11-04 12:53:00 -05:00
James Bardin 73474327a0 fix the rpc diags tests
These weren't quite done, but got lost in the huge PR.
2020-10-28 17:40:36 -04:00
James Bardin b8bed97ef4 test for RPC warnings with no errors 2020-10-28 14:51:04 -04:00
Alisdair McDiarmid fb98fc98fa terraform: Fix sensitive values in ignore changes
Because ignore_changes configuration can refer to resource arguments
which are assigned sensitive values, we need to unmark the resource
object before processing.
2020-10-20 12:27:17 -04:00
James Bardin a0caed541d remove legacy ApplyFn from mock provisioner 2020-10-08 13:13:13 -04:00
James Bardin ea5ee39f38 remove old mock provider ConfigureFn 2020-10-08 12:26:12 -04:00
James Bardin 0a6853a3f8 replace testDiffFn and testApplyFn
Replace the old mock provider test functions with modern equivalents.
There were a lot of inconsistencies in how they were used, so we needed
to update a lot of tests to match the correct behavior.
2020-10-08 11:47:34 -04:00
James Bardin 32681190ca
Merge pull request #26458 from hashicorp/jbardin/data-ref-index
data sources with indexed references to managed resources
2020-10-02 13:27:28 -04:00
James Bardin ac526d8d5d always load instance state when -refresh=false
The loading of the initial instance state was inadvertently skipped when
-refresh=false, causing all resources to appear to be missing from the
state during plan.
2020-10-01 16:04:35 -04:00
James Bardin 78322d5843 data depends_on with indexed references
If a data source refers to a indexed managed resource, we need to
re-target that reference to the containing resource for planning.  Since
data sources use the same mechanism as depends_on for managed resource
references, they can only refer to resources as a whole.
2020-10-01 14:10:09 -04:00
James Bardin 98124637d8 apply ignore_changes directly to config
In order to ensure all the starting values agree, and since
ignore_changes is only meant to apply to the configuration, we need to
process the ignore_changes values on the config itself rather than the
proposed value.

This ensures the proposed new value and the config value seen by
providers are coordinated, and still allows us to use the rules laid out
by objchange.AssertPlanValid to compare the result to the configuration.
2020-09-29 13:15:30 -04:00
James Bardin ba7a57d3c5
Merge pull request #26375 from hashicorp/jbardin/data-force-plan-read
data source depends_on
2020-09-25 13:57:06 -04:00
James Bardin ea9096fb21 data source depends_on
A data source referencing another data source through depends_on should
not be forced to defer until apply. Data sources have no side effects,
so nothing should need to be applied. If the dependency has a
planned change due to a managed resource, the original data source will
also encounter that further down the list of dependencies.

This prevents a data source being read during plan for any reason from
causing other data sources to be deferred until apply. It does not
change the behavior noticeably in 0.14, but because 0.13 still had
separate refresh and plan phases which could read the data source, the
deferral could cause many things downstream to become unexpectedly
unknown until apply.
2020-09-25 13:46:47 -04:00
Kristin Laemmert 90655b98b0 terraform: rename mustReourceAddr to mustConfigResourceAddr and add mustAbsResourceAddr
there are too many things that can be called resource addrs and it can
be hard to find the must* I'm looking for, so I renamed one and added
another.
2020-09-25 09:29:18 -04:00
James Bardin b16c600edc verify skipRefresh during plan 2020-09-24 09:34:49 -04:00
James Bardin 6039622111 Simplify data lifecycle for the no-refresh world
Now that we don't have to handle data sources that may or may not have
been updated during a refresh phase, and the plan phase can save the
data source to the refreshed state, we can remove a lot of the logic
involved in detecting whether the data source needs to be planned or
not.

When there is no separate refresh phase, we always must attempt to read
the data source during planning, and the only conditions are based on
having a known configuration, and not having any dependencies on which
we're waiting. If the data source is read during plan, we can now save
that directly to the refreshed state, and don't need to smuggle the
value as a change to be saved during apply.
2020-09-22 09:55:19 -04:00
James Bardin 8b31808843 delay data source reads with pending resource ref
Treat any reference from a data source to a managed resource as a
dependency on the entire resource. While a resource's
attribute may be statically resolvable from the configuration, if the
user added a reference to that resource, it stands to reason that the
user intended there to be a dependency which we need to wait on.

This is an extension of an implicit behavior that existed previously in
Terraform, but was lost in the 0.13 release. That behavior was emergent
from the fact that the Refresh walk did not process the configuration
for managed resources, so any new resources in the config would be
evaluate as entirely unknown during Refresh, even if some attributes
were statically resolvable at that point.

This new implementation restores the old behavior, and extends it to
updates and replacements of the referenced resource.
2020-09-18 09:10:45 -04:00
James Bardin 669da06515 saved read data in the refresh state during plan
This only changes the refreshed state stored in the plan file. Since the
change is stored in the plan, the applied result would be the same, but
we should still store the refreshed data in the plan file for tools that
consume the plan file.

This will also be needed in order to implement a new refresh command
based on the plan itself.
2020-09-17 17:12:10 -04:00
Alisdair McDiarmid e77c367345
Merge pull request #26273 from hashicorp/alisdair/sensitive-variable-plan-tests
Extend sensitive variable plan tests
2020-09-17 12:07:17 -04:00
James Bardin 1fa3503acd fixup last tests that need correct state 2020-09-17 09:54:59 -04:00
Alisdair McDiarmid e1a41daf9b terraform: Test sensitive values in module inputs
Passing a sensitive value as a module input variable should preserve its
sensitivity for the plan.
2020-09-16 16:54:04 -04:00
Alisdair McDiarmid 9e340ab85b terraform: Expand sensitive variable plan test
Test that the changes which use the sensitive variable have
corresponding path value marks. Also remove the unrelated validate
function from this test.
2020-09-16 16:48:28 -04:00
Pam Selle 4034cf9f75 Add basic plan test coverage
This also unearthed that the marking must happen
earlier in the eval_diff in order to produce a valid plan
(so that the planned marked value matches the marked config
value)
2020-09-10 16:06:37 -04:00
James Bardin b9e076ec66 re-add ModuleInstance -> Module conversion
When working with a ConfigResource, the generalization of a
ModuleInstance to a Module was inadvertently dropped, and there was to
test coverage for that type of target.

Ensure we can target a specific module instance alone.
2020-08-12 10:22:13 -04:00
James Bardin 0df5a7e6cf Generalize target addresses before expansion
Before expansion happens, we only have expansion resource nodes that
know their ConfigResource address. In order to properly compare these to
targets within a module instance, we need to generalize the target to
also be a ConfigResource.

We can also remove the IgnoreIndices field from the transformer, since
we have addresses that are properly scoped and can compare them in the
correct context.
2020-08-12 10:12:43 -04:00
James Bardin da644568a5 return known empty containers during plan
When looking up a resource during plan, we need to return an empty
container type when we're certain there are going to be no instances.
It's now more common to reference resources in a context that needs to
be known during plan (e.g. for_each), and always returning a DynamicVal
her would block plan from succeeding.
2020-07-23 17:37:07 -04:00
James Bardin f433228906 hide empty plans for misbehaving data resource
If a data source is storing a value that doesn't comply precisely with
the schema, it will now show up as a perpetual diff during plan.

Since we can easily detect if there is no resulting change from the
stored value, rather than presenting a planned read each time, we can
change the plan to a NoOp and log the incongruity as a warning.
2020-06-18 19:21:19 -04:00
James Bardin 02167dcfe4 test whole module reference from module var
this reference isn't being connected properly
2020-06-15 20:45:23 -04:00