-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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
Terraform 0.13 complains that all list elements must have the same type, while 0.12 does not. #26265
Comments
Thanks for reporting this @marcosdiez. I can't reproduce the issue without more information. Can you provide a small configuration that I can use to reproduce the error message? |
Hi. Sorry for the delay. it needs 3 files:
To test, one must type: with terraform 0.12.x it will work as expected. ===========================BEGIN OF main.tf ======================
===========================END OF main.tf ====================== ===========================BEGIN OF m1/m1.tf ======================
===========================END OF m1/m1.tf ====================== ===========================BEGIN OF m2/m2.tf ======================
===========================END OF m2/m2.tf ====================== |
Thank you, this is super helpful! I'm able to reproduce with these steps, and also confirm that the issue is present in Terraform 0.14.0-dev. |
An initial debugging session indicates that Terraform is trying to convert the |
While investigating this a bit further, I found a workaround that might be useful to you. If you specify the full type of the input variable to m2, Terraform's type checking works correctly: variable "target_subnets" {
type = list(object({
name = string
value = object({
cidr_block = string
tg_attachment_id = string
})
}))
default = []
}
output "target_subnets" {
value = var.target_subnets
} Hopefully this applies to your real configuration, too! I currently still think this is a bug, and I'm going to keep looking into it for now. |
Hey, this is a nice trick. Although I also think this is a bug, it does solve all my problems with the additive of making my modules have strict typing. Dumb question, are these "complex types" in the terraform documentation ? I can't remember seeing them. |
Yes, there's documentation on structural types on this page. The example for defining a full object type isn't very prominent, though, so perhaps we could improve that. |
Thank you for showing me yet another trick! |
After some debugging, I have more of an idea of what's happening here. When the type of the module input is just As noted in the comments there, "this is a special case where the caller wants us to find a suitable single type that all elements can convert to, if possible." The problem comes when one of the elements is unknown/dynamic, as is the case with the output from module m1. This results in hitting this block of code: // If the list element type after unification is still the dynamic
// type, the only way this can result in a valid list is if all values
// are of dynamic type
if listEty == cty.DynamicPseudoType {
for _, tupleEty := range tupleEtys {
if !tupleEty.Equals(cty.DynamicPseudoType) {
return nil
}
}
} Because the other element in the list is of a known type, The above block of code was added (by me 🥴) in response to a panic caused by using I think this is enough digging to warrant the "explained" label on this ticket, although whoever picks it up will still have to figure out a way forward that doesn't break existing behaviour in cty or Terraform itself. |
I'm running into this too, but there is no way out in my situation ... I have a YAML config that I'm deserializing with Terraform describing my
If I specify:
This results in the error above:
I've tried specifying Question: in the example above, how would you define the Some workarounds that could be added to Terraform to allow such inputs:
|
This is not currently possible. All objects must have the same type, and at the moment that means they must have valid values for each of the attributes. For now, the workaround is to adjust your data such that each element has all of the attribute names present, with suitable empty values (e.g. I have better news for the future, though! In 0.14.0, we are releasing an experimental optional object argument feature, which we hope to stabilize by 0.15.0. If you have time to try that out and give feedback, that would be much appreciated. |
I am having issues while trying to do the same like maps of AWS resources. In @alisdair 's example, I can get defaults for I am trying to upgrade from 0.12 to 0.15, but because of this issue, am facing issues getting to 0.13. One of the examples:
I tried to do the following hack
and replaced |
@Varun-garg We use GitHub issues for tracking bugs and enhancements, rather than for questions. While we can sometimes help with certain simple problems here, it's better to use the community forum where there are more people ready to help. The GitHub issues here are monitored only by our few core maintainers. Please consider asking your question in the community forum. Thanks! |
Hi again, all! Terraform v1.3.0 includes a final, stable version of the "optional attributes" feature that @alisdair mentioned as an experiment in an earlier comment. This now allows describing an object type constraint which will accept input objects that lack particular attributes, in which case Terraform will automatically fill them in with placeholder default values during type conversion to still achieve a value of the specified type constraint. Looking at the comment with an example of an variable "config" {
type = object({
# ...
exporters = list(object({
class = string
project_id = optional(string)
dataset_id = optional(string)
metrics = optional(set(string), [])
api_key = optional(string)
app_key = optional(string)
api_token = optional(string)
api_url = optional(string)
}))
})
} I imagine that the intent here was to select a different subset of attributes depending on the value of Although it was not intentional that the unification behavior changed as a result of fixing the panic in zclconf/go-cty#56, we don't plan to reintroduce the panic just to recover the previous implicit type inference behavior, and we typically consider it better to write out explicit type constraints anyway... Therefore, given how long the new behavior has been in place and given that the change was made to avoid a crash, I don't expect the previous behavior to be restored exactly as it was in Terraform v0.12. If you are encountering a problem where Terraform cannot automatically infer what collection element type you intend to use, the usual answer will be to write a more specific type constraint so that Terraform can tell exactly what type you're intending, instead of trying to guess. If you have particularly tricky examples that you're not sure how to specify, please start a topic about it in the community forum where we'll be happy to help with specific situations and suggest how to model them within the design of Terraform's type system. Thanks! |
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. |
The issue I am describing fails on Terraform v0.13.3 and works on Terraform v.0.12.29
I have a terraform module that adds routes to aws transit gateway (it's not provider related, though).
These routes come either from other modules or can be added manually.
This is how it looks like:
route_target, on the other hand, is defined as such:
In other words, it's the same structure. Terraform 12 is fine with it, Terraform 13 gives me the following error message:
I consider this a regression. If this can't be simply fixed, can we have a "cast" command ?
Thanks you!
The text was updated successfully, but these errors were encountered: