Closed apparentlymart closed 7 years ago
After further testing I found that there are some cases not caught here, because the type-checker is still short-circuiting in certain cases and ending up passing through things that the evaluator doesn't understand.
I'm going to work on a follow-up change to fix this.
Previously there was a hard rule that if a list or map contains any unknown values then the collection as a whole is unknown. This kept the handling of this situation in one spot, but was non-ideal since it is safe to use the index operator
[...]
on a partially-unknown list or map and access the values that are known.This change removes the unilateral rule that any nested unknowns immediately collapse to a single top-level unknown, which then requires each of the eval node implementations to provide their own handling of unknowns. In return for this extra complexity, we are able to make an exception in the handling of the index operator to allow the retrieval of any known values in a partially-unknown collection.
The new rules are:
If the ultimate evaluation result is a partially-unknown collection, we flatten to a top-level unknown before returning in order to keep things simple for callers.
When evaluating a function call, if any arguments are unknown or contain any unknowns then we skip calling the function and immediately return unknown. This avoids the need for function implementations to consider unknown values.
Arithmetic operators are lowered to calls to builtin functions, so these are dealt with using the same logic as function calls.
When evaluating
? :
conditionals, if the condition itself is unknown then the result is unknown. We don't check the known-ness of the two result values, since passing through an unknown here is fine.For the index operator
[...]
we return unknown if the collection itself is unknown as a whole, or if the key is unknown. Otherwise we just take the value from the collection, accepting that it might itself be unknown.For output nodes, if any of the concatenated nodes are unknown then the entire result is unknown.
These new rules are covered by some additional test cases since now it's well worth testing the
TypeUnknown
handling for each node type separately.The primary use-case for this is dealing with Terraform's "splat syntax", which allows retrieving a list of attribute values from a list of instances of a single resource, like
aws_instance.foo.*.id
. Currently this is problematic because adding a new instance (by increasing "count") adds a new computed item to the end of this list and in turn makes the whole list become Unknown. With this change, only the values correponding to the new instances will be considered as Unknown, leaving existing resources undisturbed. This use-case is discussed in more detail in hashicorp/terraform#3449 .