Provider Functions: Equivalent to schema.ListNestedAttribute?

Looking for a documentation example for Provider Functions which is analogous to schema.ListNestedAttribute for Data Sources. (Plugin Development - Framework: List Type | Terraform | HashiCorp Developer)

provider::PROVIDER::FUNCTION(
    "This is a string.",
    [
      {
        a = "one"
        b = "two"
      },
    ]
)

Essentially, I’d like my function to accept a list of maps of strings. The Go equivalent is:

[]map[string]string

Any pointers? The official TPF docs are light on examples of nesting maps. (Plugin Development - Framework: List Function Parameter | Terraform | HashiCorp Developer)

Wondering if this is a CustomType situation. (function package - github.com/hashicorp/terraform-plugin-framework/function - Go Packages)

Hi there @skyzyx :wave: ,

Based on the Go type you described you can utilize ListParameter with a types.MapType. Definition would look like:

func (f *TestFunction) Definition(ctx context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
	resp.Definition = function.Definition{
		Parameters: []function.Parameter{
			function.ListParameter{
				Name: "list_with_map", // This field is required.
				ElementType: types.MapType{
					ElemType: types.StringType,
				},
			},
		},
		// Just hardcoding a return for example
		Return: function.BoolReturn{},
	}
}

func (f *TestFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
	var listOfMaps []map[string]string
	resp.Error = req.Arguments.Get(ctx, &listOfMaps)
	if resp.Error != nil {
		return
	}
	// Just hardcoding a return for example
	resp.Error = resp.Result.Set(ctx, types.BoolValue(true))
}

If you put a breakpoint in that function the reflection rules will give you something like this:

image

1 Like

Whoops, I forgot to attach the sample Terraform config :laughing:

output "test" {
  value = provider::examplecloud::test_func(
    [
      {
        a = "one"
        b = "two"
      },
      {
        c = "three"
        d = "four"
      },
    ]
  )
}

1 Like

This is very helpful. Thank you!

1 Like

Random slightly related shout since I got this notification today.

We are introducing a change to provider function definitions where the Name field will now be required for all parameters, see: Require provider-defined function parameter naming by bendbennett · Pull Request #964 · hashicorp/terraform-plugin-framework · GitHub

The reason I mention that here is because my original example above did not have a Name parameter. I have edited the response since, but the full valid parameter definition for future travelers is:

func (f *TestFunction) Definition(ctx context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
	resp.Definition = function.Definition{
		Parameters: []function.Parameter{
			function.ListParameter{
				Name: "list_with_map", // This is now required.
				ElementType: types.MapType{
					ElemType: types.StringType,
				},
			},
		},
		// Just hardcoding a return for example
		Return: function.BoolReturn{},
	}
}