-
Notifications
You must be signed in to change notification settings - Fork 95
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
Support dynamic types in collections #973
Comments
Hey there @sebhoss 👋, thanks for reporting the issue.
It is possible to support the equivalent of a
What is possibleIn Terraform, a collection type is multiple elements of a single element type, that's to say when a type constraint like So given the following configuration, assuming resource "examplecloud_thing" "test" {
# tuple[number, string, bool] -> list(string), success! found single type of string
example_attribute = [1234, "http", true]
} So if the feature request here is focused on allowing Terraform to determine a single element type of a collection at runtime, then I believe that's possible to achieve. What is not possibleThe same resource "examplecloud_thing" "test" {
# tuple[number, bool] -> error! no single type found :(
example_attribute = [1234, true]
} It's not possible for us to define a constraint that would allow a collection that contains "multiple" element types, like Current WorkaroundSuggesting the usage of Adding a list of objects into the mix makes your specific situation a little more complicated in-terms of handling, so I would tend to agree with you that it's not worth it in your situation of The simplest way to test that kind of "type conversion" is with a little output and conversion: output "test" {
value = tolist([123, "456", 789])
} State output: {
"version": 4,
"terraform_version": "1.8.0",
"serial": 26,
"lineage": "87f4a8d4-57e7-2f4e-d081-aef9e7e6b675",
"outputs": {
"test": {
"value": [
"123",
"456",
"789"
],
"type": [
"list",
"string"
]
}
},
"resources": [],
"check_results": null
} |
Hey @austinvalle thanks for the detailed response! I did not consider automatic type conversion here at all and after playing around with it for a while, I think it does solve my immediate use case quite well. Feel free to close this ticket & thanks again for the pointers ❤️ |
No problem! I'm going to leave this issue open to collect any potential use-cases from future readers since there is functionality that can be added here, as long as it can fit inside Terraform's type system. Terraform Type documentation: |
While this topic is fresh, it is possible to achieve the I built a small "dynamic list" implementation in my sandbox provider@836539:
For this example, if you were to run {
"format_version": "1.0",
"provider_schemas": {
"registry.terraform.io/austinvalle/sandbox": {
"provider": {
"version": 0,
"block": {
"description_kind": "plain"
}
},
"resource_schemas": {
"examplecloud_thing": {
"version": 0,
"block": {
"attributes": {
"list_with_dynamics": {
"type": [
"list",
"dynamic"
],
"description_kind": "plain",
"required": true
}
},
"description_kind": "plain"
}
}
}
}
}
}
|
@austinvalle This would be super useful for those APIs made with FastAPI or Django where its pretty common to use Union types for certain attributes. ...
"input": schema.ListNestedAttribute{
Required: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Required: true,
},
"description": schema.StringAttribute{
Optional: true,
},
"multiple": schema.BoolAttribute{
Required: true,
},
"required": schema.BoolAttribute{
Required: true,
},
"sensitive": schema.BoolAttribute{
Required: true,
},
"value": schema.DynamicAttribute{
Required: true,
},
},
},
},
... In our case we expect value being a float, str, bool, [int], [float], [str] or [bool]. |
Thanks for the example @smartinellimarco! Just a few thoughts to make sure we're on the same page. In your example where For example, the following two configurations would be valid: # Resulting type would be list(object({value=list(string)}))
output "input_example_1" {
value = tolist(
[
{ value = tolist(["one", "two"]) },
{ value = tolist(["three", "four"]) },
{ value = tolist(["five", "six"]) },
]
)
}
# Resulting type would be `list(object({value=string}))`
output "input_example_2" {
value = tolist(
[
{ value = "one" },
{ value = "two" },
{ value = 3 },
{ value = false },
]
)
} However this would be invalid: output "input_example" {
value = tolist(
[
{ value = "one" },
{ value = "two" },
{ value = tolist(["three", "four"]) },
]
)
} Depending on the underlying API implementation, that may not be the same expectation, so wanted to be upfront on what is actually possible. Given that, the types you'd be able to achieve with this constraint would be restricted to one of the following:
|
I think this is really useful in scenarios where you need to pass arbitrary objects with arbitrary keys and values to another system. It is possible to do that by converting to json in the terraform code and then decoding it in the provider, but that step could be skipped if this was done automatically in some way. |
Module version
Use-cases
I'm trying out the new dynamic types in version 1.7 and encountered a limitation while trying to use a dynamic type within a collection. My guess is that is the same underlying restriction I previously reported in #147 and therefore (almost?) impossible to fix. However I'm not that deep into the internals of terraform, thus I wanted to ask/clarify whether dynamic types in collections will ever be supported or not.
Attempted Solutions
I simply used my custom dynamic type within a collection and got the following error:
The suggestion to change the type of the collection itself to a DynamicAttribute might work, however I fear that this will require lots of attributes to be changed to dynamics and therefore a heavy loss on static type information.
Proposal
Well if it is at all possible, I'd love to have support for dynamic types in collections. If that's not possible, my immediate use case (an IntOrString type) will be solved the same way I do it today: Declare the type as string and tell users that this is something they have to keep in mind while using the provider.
References
#147
metio/terraform-provider-k8s#119
The text was updated successfully, but these errors were encountered: