This also fixes a few things with resource for_each:
It makes validation more like validation for count.
It makes sure the index is stored in the state properly.
// We currently parse this, but don't yet do anything with it.
diags=append(diags,&hcl.Diagnostic{
Severity:hcl.DiagError,
Summary:"Reserved argument name in module block",
Detail:fmt.Sprintf("The name %q is reserved for use in a future version of Terraform.",attr.Name),
Subject:&attr.NameRange,
})
// Cannot have count and for_each on the same data block
ifr.Count!=nil{
diags=append(diags,&hcl.Diagnostic{
Severity:hcl.DiagError,
Summary:`Invalid combination of "count" and "for_each"`,
Detail:`The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.`,
// Currently this is a rather bad outcome from a UX standpoint, since we have
// no real mechanism to deal with this situation and all we can do is produce
// an error message.
// FIXME: In future, implement a built-in mechanism for deferring changes that
// can't yet be predicted, and use it to guide the user through several
// plan/apply steps until the desired configuration is eventually reached.
diags=diags.Append(&hcl.Diagnostic{
Severity:hcl.DiagError,
Summary:"Invalid forEach argument",
Detail:`The "for_each" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use the -target argument to first apply only the resources that the for_each depends on.`,
})
panic("uh-oh")
}
returnforEachMap,diags
}
// evaluateResourceForEachExpressionKnown is like evaluateResourceForEachExpression
// except that it handles an unknown result by returning an empty map and
// a known = false, rather than by reporting the unknown value as an error
Detail:fmt.Sprintf(`The given "for_each" argument value is unsuitable: the "for_each" argument must be a map, or set of strings, and you have provided a value of type %s.`,forEachVal.Type().FriendlyName()),
Detail:fmt.Sprintf(`The given "for_each" argument value is unsuitable: "for_each" supports maps and sets of strings, but you have provided a set containing type %s.`,forEachVal.Type().ElementType().FriendlyName()),
Subject:expr.Range().Ptr(),
})
returnnil,diags
returnnil,true,diags
}
}
// If the map is empty ({}), return an empty map, because cty will return nil when representing {} AsValueMap
// Also return an empty map if the value is not known -- as this function
// is used to check if the for_each value is valid as well as to apply it, the empty