New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Confusing error message "map of object is required" or "list of object is required" for a variable default value #19141
Comments
Over in #19278 we can see a different variation of this problem: Terraform was able to infer a type from the default successfully but it inferred an overly-specific type. In that case, it inferred an object with an exact set of keys rather than a While our usual behavior for type inference is to choose the most precise type that matches the value, I think the requirements for Perhaps then the appropriate behavior is to run an additional step at the end of the normal type inference if the normal inferencer selected a tuple or object type: if all of the elements can be unified to a single element type, simplify the inferred type to be a list or map type instead. For example:
The effect of this is that users that are intending to use the new structural types will need to define Since prior versions of Terraform did not support these structural types at all, it may be best for us to require a typed-by-example variable to reduce to a collection type and produce a good error message if not explaining how to set the |
I did some more testing after #19690 is merged and it seems as if that has actually addressed the core problems here. Looking more closely now, I realize that the type unification improvements in cty have fixed the rough edges here by allowing Terraform to find a suitable type without any special additional rules. With that said, then, I'm going to close this out now and we'll make a fresh issue if we find more obscure problems in this area during further testing. To verify this I used a child module with the following content: variable "list" {
default = ["a", "b", 1]
}
variable "map" {
default = {
a = "a"
b = 1
c = "c"
}
}
variable "list_of_map" {
default = [
{},
{
a = 1
b = "b"
c = "c"
},
]
} I then called it with some values that have similar-but-not-identical types: module "child" {
source = "./child"
list = [1, "b"]
map = {
a = 1
b = "b"
}
list_of_map = [
{
a = 1
b = "b"
}
]
} Terraform now accepts this without error. |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
Terraform Version
Terraform Configuration Files
Expected Behavior
When encountering a
variable
block without an explicittype
argument, Terraform should use the type of the default value to infer the variable's type.In the above case, the expected inferred type would be
map(list(string))
.Actual Behavior
Officially, Terraform versions prior to v0.12 only supported flat lists and maps for variable values. However, due to some implementation bugs in validation it was possible to introduce more complex data structures as variable defaults, including structures that would violate the usual rule that all elements of a list or map must be of the same type. While this usually led to downstream errors while working with that invalid expression, certain simple expressions could also pass validation.
Terraform v0.12 now does more complete validation of variable values in order to improve the user experience for callers of modules, allowing for more precise and actionable error messages to be returned. For compatibility with existing usage, Terraform v0.12 attempts to infer a reasonable type specification for any default value, but in v0.12-alpha1 the type inference mechanism is not able to correctly infer more complex structures like lists of lists, maps of lists, etc.
When inference fails, Terraform may produce a confusing error message such as "object is required", even though the value appears to be an object. When Terraform presents this message, what it means to say is that the object it found is not of the expected type, which results from Terraform being unable to decide on a suitable object type to use for validation.
Workaround
To work around this for v0.12-alpha1 testing, set an explicit
type
argument to avoid the need for the automatic type detection heuristic:As long as the given default can be converted to the specified type, the default value should be accepted. Note that the
map
,list
andset
type kinds require all of their elements to be of the same type. For more information on the 0.12 language type system, see the Types and Values draft documentation.The text was updated successfully, but these errors were encountered: