Hi @jason-johnson Thank you for raising this great topic and welcome to HashiCorp Discuss!
I think we might want to see some additional details about what exactly you are trying or wanting to do, but I will attempt to answer this using my reading that you are looking to create function(s) that have two required arguments, then three function configuration options that constitute optional argument(s). If I misunderstood, please let me know!
In this sort of setup, the function definition might be something like:
- Parameter 1: Whatever type required
- Parameter 2: Whatever type required
- Parameter 3: Object with three object attributes representing the three function configuration options. This could enable the AllowNullValue flag so practitioners don’t need to necessarily pass an empty/unconfigured object of
{}
.
As you found, in Terraform, maps are collection types which have a single element type. Objects are mappings of specific object attribute names to values. Those values can have differing types.
This would be represented in configuration calls as (with comments describing how the data looks to the function logic):
# null object
provider::TYPE::NAME(param1, param2, null)
# empty object (all options are null)
provider::TYPE::NAME(param1, param2, {})
# partially configured object (option2 is null, option3 is null)
provider::TYPE::NAME(param1, param2, {
option1 = true
})
# fully configured object
provider::TYPE::NAME(param1, param2, {
option1 = true
option2 = 123
option3 = "test"
})
Another way to handle the configuration object situation, would be to switch that final parameter from a regular parameter to a variadic parameter.
In that case, configuration calls could look like:
# null tuple of objects
provider::TYPE::NAME(param1, param2)
# tuple of one null object
provider::TYPE::NAME(param1, param2, null)
# tuple of one empty object
provider::TYPE::NAME(param1, param2, {})
# tuple of one partially configured object (option2 is null, option3 is null)
provider::TYPE::NAME(param1, param2, {
option1 = true
})
# tuple of one fully configured object
provider::TYPE::NAME(param1, param2, {
option1 = true
option2 = 123
option3 = "test"
})
# tuple of multiple partially configured objects
provider::TYPE::NAME(
param1,
param2,
{
option1 = true
},
{
option2 = 123
},
)
# tuple of multiple fully configured objects
provider::TYPE::NAME(
param1,
param2,
{
option1 = true
option2 = 123
option3 = "test"
},
{
option1 = false
option2 = 456
option3 = "not-test"
}
)
As you might be able to see here, the variadic parameter option is nice in the sense that the configuration does not necessarily need to include the final argument of options, but it also complicates the situation by allowing multiple arguments, potentially with “conflicting” configuration. You would need to decide how to best handle that situation in your function logic, whether it be returning an error if multiple options are found, returning an error only if multiple “conflicting” option values are found, or having later “conflicting” options overwrite earlier options.
If you have any particular suggestions on how we can improve either the terraform-plugin-framework website documentation or Go documentation, please let us know by creating an issue in GitHub.
Thanks and hope this helps.