This commit adds an `alltrue` function to Terraform configuration. A
reason we might want this function is because it will enable more
powerful custom variable validations. For example:
```hcl
variable "amis" {
type = list(object({
id = string
}))
validation {
condition = (alltrue([
for a in var.amis : length(a.id) > 4 && substr(a.id, 0, 4) == "ami-"
]))
error_message = "The ID of at least one AMI was invalid."
}
}
```
Now that the planning process generates a refreshed state, and can
handle changes between the configuration and the state which the refresh
process cannot, we can use the plan for the refresh command.
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.
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.
The prior state recorded in the plans did not match the actual prior
state. Make the plans and state match depending on whether there was
existing state or not.
Since the refreshed state is now an artifact of the plan process, it
makes sense to add it to the Plan type, rather than adding an additional
return value to the Context.Plan method.
All resources use EvalWriteState to store their state, so we need a way
to switch the states when the resource is refreshing vs when it is
planning. (this will likely change once we factor out the EvalNode pattern)
Since plan uses the state as a scratch space for evaluation, we need an
entirely separate state to store the refreshed resources values during
planning. Add a RefreshState method to the EvalContext to retrieve a
state used only for refreshing resources.
While we like codecov, and the coverage goals, we've frequently ignored
the failures for various reasons. These have confused community members
submitting PRs and it can be confusing to look at a list of merged PRs
with the big X indicating failed checks ("confusing" isn't really a
problem, but if there were actually a bad merge, it could be hard to
find which in a list of commits actually had an important failure).
Fixes a mild inconvenience.
Test that the changes which use the sensitive variable have
corresponding path value marks. Also remove the unrelated validate
function from this test.
* remove leftover debug line
* terraform: refactor ProviderEvalTree
This PR refactors the ProviderEvalTree by folding the entire tree into
straight-through code in NodeApplyableProvider Execute (formally
EvalTree). The EvalConfigProvider functions were refactored into
NodeApplyableProvider functions (since that was the only place they were
used).
I also removed the unused node_provider_disabled code.
* revert removal of graphNodeCloseProvider EvalTree, replace with Execute
* terraform: remove unused eval node
* add UpdateStateHook function to replace EvalUpdateStateHook
* early exit error isn't
* terraform: NodeDestroyResourceInstance refactor
This PR refactor's NodeDestroyResourceInstance EvalTree() into an
Execute() node. EvalRequireState and evalWriteEmptyState were used only
by this node, and they have been removed in favor of straight code.
There are still many calls to someEvalNode.Eval() in NodeDestroyResourceInstance: I plan on refactoring the remaining EvalTree()s before tacking those Eval()s (all of which are used by many graph nodes)
I've added a new function, UpdateStateHook, that is effectively the same
as EvalUpdateStateHook. The latter will be removed when the larger
EvalNode refactor project is complete.
EvalModuleCallArguments is now a method on nodeModuleVariable, it's only
caller, and the other functions have been replaces with straight through
code (or in the case of evalVariableValidations, a standalone function).
I was unable to add tests for nodeModuleVariable.Execute, which requires
fixtures that aren't part of the MockEvalContext (a scope.evalContext is
one); it's not ideal but that function should be well covered by the
context tests so I chose to leave it as-is.
Finally, I removed the unused function hclTypeName. Deleting code is
fun!
While this was easier to spot during plan, it is also possible to
evaluate resources with 0 instances during apply as well.
This doesn't effect the failure when scaling CBD instances, it only
changes the fact that the inconsistent value is no longer unknown.