return unknown module expansions during validate
There is no expansion during validation, so in order for module references to work we need to ensure that the returned values are unknown.
This commit is contained in:
parent
d152d13bea
commit
92837e6296
|
@ -1421,6 +1421,7 @@ module "mod1" {
|
||||||
module "mod2" {
|
module "mod2" {
|
||||||
for_each = module.mod1
|
for_each = module.mod1
|
||||||
source = "./mod"
|
source = "./mod"
|
||||||
|
input = module.mod1["a"].out
|
||||||
}
|
}
|
||||||
|
|
||||||
module "mod3" {
|
module "mod3" {
|
||||||
|
@ -1432,6 +1433,15 @@ module "mod3" {
|
||||||
resource "aws_instance" "foo" {
|
resource "aws_instance" "foo" {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "out" {
|
||||||
|
value = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "input" {
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
}
|
||||||
|
|
||||||
module "nested" {
|
module "nested" {
|
||||||
count = 2
|
count = 2
|
||||||
source = "./nested"
|
source = "./nested"
|
||||||
|
|
|
@ -406,9 +406,7 @@ func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.Sourc
|
||||||
for key, states := range stateMap {
|
for key, states := range stateMap {
|
||||||
outputState, ok := states[cfg.Name]
|
outputState, ok := states[cfg.Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
// we'll take this chance to insert any missing values that are
|
continue
|
||||||
// defined in the config
|
|
||||||
outputState = cty.DynamicVal
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instance, ok := moduleInstances[key]
|
instance, ok := moduleInstances[key]
|
||||||
|
@ -446,15 +444,7 @@ func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.Sourc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure all defined outputs names are present in the module value, even
|
var ret cty.Value
|
||||||
// if they are not known yet.
|
|
||||||
for _, instance := range moduleInstances {
|
|
||||||
for configKey := range outputConfigs {
|
|
||||||
if _, ok := instance[configKey]; !ok {
|
|
||||||
instance[configKey] = cty.DynamicVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// compile the outputs into the correct value type for the each mode
|
// compile the outputs into the correct value type for the each mode
|
||||||
switch {
|
switch {
|
||||||
|
@ -470,19 +460,23 @@ func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.Sourc
|
||||||
vals[int(intKey)] = cty.ObjectVal(instance)
|
vals[int(intKey)] = cty.ObjectVal(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// we shouldn't have any holes, but insert real values just in case,
|
if len(vals) > 0 {
|
||||||
// while trimming off any extra values that we may have from guessing
|
// we shouldn't have any holes, but insert real values just in case,
|
||||||
// the length via the state instances.
|
// while trimming off any extra values that we may have from guessing
|
||||||
last := 0
|
// the length via the state instances.
|
||||||
for i, v := range vals {
|
last := 0
|
||||||
if v.IsNull() {
|
for i, v := range vals {
|
||||||
vals[i] = cty.DynamicVal
|
if v.IsNull() {
|
||||||
continue
|
vals[i] = cty.DynamicVal
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
last = i
|
||||||
}
|
}
|
||||||
last = i
|
vals = vals[:last+1]
|
||||||
|
ret = cty.ListVal(vals)
|
||||||
|
} else {
|
||||||
|
ret = cty.ListValEmpty(cty.DynamicPseudoType)
|
||||||
}
|
}
|
||||||
vals = vals[:last+1]
|
|
||||||
return cty.TupleVal(vals), diags
|
|
||||||
|
|
||||||
case callConfig.ForEach != nil:
|
case callConfig.ForEach != nil:
|
||||||
vals := make(map[string]cty.Value)
|
vals := make(map[string]cty.Value)
|
||||||
|
@ -494,20 +488,34 @@ func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.Sourc
|
||||||
|
|
||||||
vals[string(strKey)] = cty.ObjectVal(instance)
|
vals[string(strKey)] = cty.ObjectVal(instance)
|
||||||
}
|
}
|
||||||
return cty.ObjectVal(vals), diags
|
|
||||||
|
if len(vals) > 0 {
|
||||||
|
ret = cty.MapVal(vals)
|
||||||
|
} else {
|
||||||
|
ret = cty.MapValEmpty(cty.DynamicPseudoType)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
val, ok := moduleInstances[addrs.NoKey]
|
val, ok := moduleInstances[addrs.NoKey]
|
||||||
if !ok {
|
if !ok {
|
||||||
// create the object is there wasn't one known
|
// create the object if there wasn't one known
|
||||||
val = map[string]cty.Value{}
|
val = map[string]cty.Value{}
|
||||||
for k := range outputConfigs {
|
for k := range outputConfigs {
|
||||||
val[k] = cty.DynamicVal
|
val[k] = cty.DynamicVal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cty.ObjectVal(val), diags
|
ret = cty.ObjectVal(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The module won't be expanded during validation, so we need to return an
|
||||||
|
// unknown value. This will ensure the types looks correct, since we built
|
||||||
|
// the objects based on the configuration.
|
||||||
|
if d.Operation == walkValidate {
|
||||||
|
return cty.UnknownVal(ret.Type()), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
|
func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
|
||||||
|
|
Loading…
Reference in New Issue