* Add a helper for mocking a provider with a state store
* Update tests to use the new helper
* Update other test fixtures for consistency
The related tests pass before and after this change
* Update testing helper to return the underlying type, not the interface
* Enable parsing of blocks in individual files
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
* Enable handling of state stores when parsing a module from its constituent files.
This includes: validations of duplicates and clashes, supporting override files.
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
* Add tests for validation that detects conflicts between state_store blocks and others
* Add tests for state_store override behavior
* Add tests for validation that detects when conflicting state-related blocks are used, either in the same file or across separate files
* Update error message summaries to explicitly say blocks conflict
* Add small changes to assertions in state_store override tests
* Update state_store block parsing to expect scoped provider block
* Update tests following syntax change
* Make config parsing experimental
* Remove testModuleFromDirWithExperiment, as testModuleFromDirWithExperiments exists!
* Update code comment
---------
Co-authored-by: Radek Simko <radeksimko@users.noreply.github.com>
Co-authored-by: Radek Simko <radek.simko@gmail.com>
* Add comments, rename tests, reorder tests
This commit doesn't change or add any logic
* Add test for overriding a cloud block with a backend block
* Add tests showing multiple instances of cloud or backend blocks cause an error
* Add test showing that backend and cloud blocks cannot be in the same terraform block
* Add test case asserting it's not valid to have both cloud and backend blocks across files in a module
* Clarify comments and replace some comments with test names
* Replace comments with test names
Previously we introduced a language experiment that would permit variable
validation rules to refer to other objects declared in the same module
as the variable.
Now that experiment is concluded and its behavior is available for all
modules.
This final version deviates slightly from the experiment: we learned from
the experimental implementation that we accidentally made the "validate"
command able to validate constant-valued input variables in child modules
despite the usual rule that input variables are unknown during validation,
because the previous compromise bypassed the main expression evaluator
and built its own evaluation context directly.
Even though that behavior was not intended, it's a useful behavior that is
protected by our compatibility promises and so this commit includes a
slightly hacky emulation of that behavior, in eval_variable.go, that
fetches the variable value in the same way the old implementation would
have and then modifies the hcl evaluation context to include that value,
while preserving anything else that our standard evaluation context
builder put in there. That narrowly preserves the old behavior for
expressions that compare the variable value directly to a constant, while
treating all other references (which were previously totally invalid) in
the standard way. This quirk was already covered by the existing test
TestContext2Validate_variableCustomValidationsFail, which fails if the
special workaround is removed.
When a module opts in to the variable_validation_crossref experiment,
Terraform will treat variable validation rules in a similar way as any
other dynamic expression, allowing it to refer to other objects that are
declared in the same module as the variable.
Because the check for a validation rule referring only to itself is now
experiments-sensitive we need to do it only once the full module has been
assembled, rather than during assembly of individual files, and so the
"badref" test in package configs is now classified under "invalid-modules"
rather than "invalid-files". It's otherwise unchanged, and the existing
test that a validation rule must refer to at least _something_ is still
present because that remains true even when opted in to the experiment.
This is experimental for now because although it seems pretty plausible
that it should be okay, this is allowing full evaluation in a new place
where it wasn't allowed before and so we'd like to ask those interested
in this feature to try it out with some of their realistic use-cases and
make sure this solution is a good fit before we lock it in as a
compatibility constraint.
The validation for checking if an import target is the source of a moved
block is incorrect. Besides the noted FIXME of the check being incorrect
for moved modules (and also resources scoped within modules); an import
can only be statically identified at the granularity of a resource
block, but moved block can have individual instances in the `from`
field.
Since we already validate that a resource block must _not_ exist in the
config for `moved`, we can rely on that causing `import` to fail with a
nonexistant resource block during evaluation if they have the same
target.
This allows precondition and postcondition checks to be declared for
resources and output values as long as the preconditions_postconditions
experiment is enabled.
Terraform Core doesn't currently know anything about these features, so
as of this commit declaring them does nothing at all.
Based on feedback during earlier alpha releases, we've decided to move
forward with the current design for the first phase of config-driven
refactoring.
Therefore here we've marked the experiment as concluded with no changes
to the most recent incarnation of the functionality. The other changes
here are all just updating test fixtures to no longer declare that they
are using experimental features.
The current behavior of module input variables is to allow users to
override a default by assigning `null`, which works contrary to the
behavior of resource attributes, and prevents explicitly accepting a
default when the input must be defined in the configuration.
Add a new variable attribute called `nullable` will allow explicitly
defining when a variable can be set to null or not. The current default
behavior is that of `nullable=true`.
Setting `nullable=false` in a variable block indicates that the variable
value can never be null. This either requires a non-null input value, or
a non-null default value. In the case of the latter, we also opt-in to
the new behavior of a `null` input value taking the default rather than
overriding it.
In a future language edition where we make `nullable=false` the default,
setting `nullable=true` will allow the legacy behavior of `null`
overriding a default value. The only future configuration in which this
would be required even if the legacy behavior were not desired is when
setting an optional+nullable value. In that case `default=null` would
also be needed and we could therefor imply `nullable=true` without
requiring it in the configuration.
These changes allow cloud blocks to be overridden by backend blocks and
vice versa; the logic follows the current backend behavior of a block
overriding a preceding block in full, with no merges.
An earlier commit added logic to decode "moved" blocks and do static
validation of them. Here we now include that result also in modules
produced from those files, which we can then use in Terraform Core to
actually implement the moves.
This also places the feature behind an active experiment keyword called
config_driven_move. For now activating this doesn't actually achieve
anything except let you include moved blocks that Terraform will summarily
ignore, but we'll expand the scope of this in later commits to eventually
reach the point where it's really usable.
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.
If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.