core: Input variables are always unknown during validate
Earlier on in the v0.12 development cycle we made the decision that the validation walk should consider input values to always be unknown so that validation is checking validity for all possible inputs rather than for a specific set of inputs; checking for a specific set of inputs is the responsibility of the plan walk. However, we didn't implement that in the best way: we made the "terraform validate" command force all of the input variables to unknown but that was insufficient because it didn't also affect the implicit validation walk we do as part of "terraform plan" and "terraform apply", causing those to produce confusingly-different results. Instead, we'll address the problem directly in the reference resolver code, ensuring that all variable values will always be treated as an unknown (of the declared type, so type checking is still possible) during any validate walk, regardless of which command is running it.
This commit is contained in:
parent
d7f23f0beb
commit
cbc8d1eba2
|
@ -1030,7 +1030,7 @@ func TestContext2Validate_targetedDestroy(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContext2Validate_varRefFilled(t *testing.T) {
|
||||
func TestContext2Validate_varRefUnknown(t *testing.T) {
|
||||
m := testModule(t, "validate-variable-ref")
|
||||
p := testProvider("aws")
|
||||
p.GetSchemaReturn = &ProviderSchema{
|
||||
|
@ -1064,7 +1064,11 @@ func TestContext2Validate_varRefFilled(t *testing.T) {
|
|||
}
|
||||
|
||||
c.Validate()
|
||||
if !value.RawEquals(cty.StringVal("bar")) {
|
||||
|
||||
// Input variables are always unknown during the validate walk, because
|
||||
// we're checking for validity of all possible input values. Validity
|
||||
// against specific input values is checked during the plan walk.
|
||||
if !value.RawEquals(cty.UnknownVal(cty.String)) {
|
||||
t.Fatalf("bad: %#v", value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,6 +215,23 @@ func (d *evaluationStateData) GetInputVariable(addr addrs.InputVariable, rng tfd
|
|||
d.Evaluator.VariableValuesLock.Lock()
|
||||
defer d.Evaluator.VariableValuesLock.Unlock()
|
||||
|
||||
// During the validate walk, input variables are always unknown so
|
||||
// that we are validating the configuration for all possible input values
|
||||
// rather than for a specific set. Checking against a specific set of
|
||||
// input values then happens during the plan walk.
|
||||
//
|
||||
// This is important because otherwise the validation walk will tend to be
|
||||
// overly strict, requiring expressions throughout the configuration to
|
||||
// be complicated to accommodate all possible inputs, whereas returning
|
||||
// known here allows for simpler patterns like using input values as
|
||||
// guards to broadly enable/disable resources, avoid processing things
|
||||
// that are disabled, etc. Terraform's static validation leans towards
|
||||
// being liberal in what it accepts because the subsequent plan walk has
|
||||
// more information available and so can be more conservative.
|
||||
if d.Operation == walkValidate {
|
||||
return cty.UnknownVal(wantType), diags
|
||||
}
|
||||
|
||||
moduleAddrStr := d.ModulePath.String()
|
||||
vals := d.Evaluator.VariableValues[moduleAddrStr]
|
||||
if vals == nil {
|
||||
|
|
Loading…
Reference in New Issue