I need help with Map / Object types

I have a map[string]interface{} object that I’m trying to set as a value in my custom data source.

I have sort of solved it 2 different ways but neither method is quite how I would like it.

In the first method I use a schema.MapAttribute which must define a a ElementType. The major drawback is that the element type must be consistent for all keys in the map or the plugin will panic

schema.MapAttribute{
	Description: "My map attribute.",
 	ElementType: types.StringType,
 	Computed:    true,
},

The second method I use a schema.ObjectAttribute which must define AttributeTypes. The major drawback with this method is that attribute types must be known in advance by defining each key and key value type which makes the structure very rigid and inflexible.

schema.ObjectAttribute{
	Description: "My object attribute.",
	Computed:    true,
	AttributeTypes: map[string]attr.Type{
		"a": types.StringType,
		"b": types.Int64Type,
	},
},

I’m trying to achieve a hybrid of the two methods but I can’t seem to figure it out and I’m wondering if its even possible within the confines of golang. Ideally I could have a map like in method 1 but the types wouldn’t be strictly limited to whats specified in the ElementType

Any help would be greatly appreciated

Hi @jbills :wave: Welcome to HashiCorp Discuss and thank you for raising this topic.

What you have discovered here are design choices for Terraform’s type system. Maps are a key-value mapping type with a single element type and objects are an attribute-value mapping type with fixed attributes. Some of this is further discussed in the type constraints documentation, however for a deeper dive into Terraform’s type system implementation, the cty specification (for that side of the provider protocol) goes further into those details.

Terraform does support some notions of dynamic typing (DynamicPsuedoType), which is accessible to providers built on top of the lower level terraform-plugin-go SDK, however that may be an overly complex solution for your situation.

Thanks @bflad, I understand now. While I find the terraform-plugin-framework a convenient abstraction for terraform-plugin-go, it looks like I’ll need to go off on the deep end and start building my plugin without the framework.

I have only performed a cursory glance of the reading material you shared but my high level understanding is that I can clone terraform-plugin-go and build my plugin modifying that code base? Or do I need to write a plugin that imports terraform-plugin-go, implement all the RPC calls, and invoke a tf6server? If there are examples of plugins building on top of terraform-plugin-go can you share with me? Are there any hashicorp examples/tutorials?

Thanks