---
page_title: 'Plugin Development - Framework: Dynamic Function Parameter'
description: >-
  Learn the dynamic function parameter type in the provider development framework.
---

# Dynamic Function Parameter

<Tip>

Static types should always be preferred over dynamic types, when possible.

Developers creating a function with a dynamic parameter will need to have extensive knowledge of the [Terraform type system](/terraform/language/expressions/types), as no type conversion will be performed to incoming argument data.

Refer to [Dynamic Data - Considerations](/terraform/plugin/framework/handling-data/dynamic-data#considerations) for more information.

</Tip>

Dynamic function parameters can receive **any** value type from a practitioner configuration. Values are accessible in function logic by the [framework dynamic type](/terraform/plugin/framework/handling-data/types/dynamic).

In this Terraform configuration example, a dynamic parameter is set to the boolean value `true`:

```hcl
provider::example::example(true)
```

In this example, the same dynamic parameter is set to a tuple (not a list) of string values `one` and `two`:

```hcl
provider::example::example(["one", "two"])
```

In this example, the same dynamic parameter is set to an object type with mapped values of `attr1` to `"value1"` and `attr2` to `123`:

```hcl
provider::example::example({
    attr1 = "value1",
    attr2 = 123,
})
```

## Function Definition

Use the [`function.DynamicParameter` type](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/function#DynamicParameter) in the [function definition](/terraform/plugin/framework/functions/implementation#definition-method) to accept a dynamic value.

In this example, a function definition includes a first position dynamic parameter:

```go
func (f ExampleFunction) Definition(ctx context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
    resp.Definition = function.Definition{
        // ... other Definition fields ...
        Parameters: []function.Parameter{
            function.DynamicParameter{
                Name: "dynamic_param",
                // ... potentially other DynamicParameter fields ...
            },
        },
    }
}
```

Dynamic values are not supported as the element type of a [collection type](/terraform/plugin/framework/handling-data/types#collection-types) or within [collection parameter types](/terraform/plugin/framework/functions/parameters#collection-parameter-types).

If the dynamic value should be a value type of an [object parameter type](/terraform/plugin/framework/functions/parameters#object-parameter-type), set the `AttributeTypes` map value according to the [framework dynamic type](/terraform/plugin/framework/handling-data/types/dynamic). Refer to the object parameter type documentation for additional details.

### Allow Null Values

<Highlight>

A known dynamic value with an underlying value that contains nulls (such as a list with null element values) will always be sent to the function logic, regardless of the `AllowNullValue` setting. Data handling must always account for this situation.

</Highlight>

By default, Terraform will not pass null values to the function logic. Use the `AllowNullValue` field to explicitly allow null values, if there is a meaningful distinction that should occur in function logic.

### Allow Unknown Values

By default, Terraform will not pass unknown values to the function logic. Use the `AllowUnknownValues` field to explicitly allow unknown values, if there is a meaningful distinction that should occur in function logic.

### Custom Types

You may want to build your own data value and type implementations to allow your provider to combine validation and other behaviors into a reusable bundle. This helps avoid duplication and ensures consistency. These implementations use the `CustomType` field in the parameter type.

Refer to [Custom Types](/terraform/plugin/framework/handling-data/types/custom) for further details on creating provider-defined types and values.

### Documentation

Refer to [function documentation](/terraform/plugin/framework/functions/documentation) for information about the `Name`, `Description`, and `MarkdownDescription` fields available.

## Reading Argument Data

The [function implementation](/terraform/plugin/framework/functions/implementation) documentation covers the general methods for reading function argument data in function logic.

When retrieving the argument value for this parameter:

* If `CustomType` is set, use its associated value type.
* Otherwise, you must use the [framework dynamic type](/terraform/plugin/framework/handling-data/types/dynamic).

In this example, a function defines a single dynamic parameter and accesses its argument value:

```go
func (f ExampleFunction) Definition(ctx context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
    resp.Definition = function.Definition{
        // ... other Definition fields ...
        Parameters: []function.Parameter{
            function.DynamicParameter{
                Name: "dynamic_param",
                // ... potentially other DynamicParameter fields ...
            },
        },
    }
}

func (f ExampleFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
    var dynamicArg types.Dynamic

    resp.Error = function.ConcatFuncErrors(resp.Error, req.Arguments.Get(ctx, &dynamicArg))

    // dynamicArg is now populated
    // ... other logic ...
}
```

For more detail on working with dynamic values, see the [framework dynamic type](/terraform/plugin/framework/handling-data/types/dynamic) documentation.

## Using Dynamic as a Variadic Parameter

Utilizing `function.DynamicParameter` in the [`VariadicParameter`](/terraform/plugin/framework/functions/implementation#reading-variadic-parameter-argument-data) field will allow zero, one, or more values of **potentially different** types.

To handle this scenario of multiple values with different types, utilize [`types.Tuple`](/terraform/plugin/framework/handling-data/types/tuple) or [`[]types.Dynamic`](/terraform/plugin/framework/handling-data/types/dynamic) when reading a dynamic variadic argument.

```go
func (f *ExampleFunction) Definition(ctx context.Context, req function.DefinitionRequest, resp *function.DefinitionResponse) {
    resp.Definition = function.Definition{
        // ... other Definition fields ...
        VariadicParameter: function.DynamicParameter{
            Name: "variadic_param",
        },
    }
}

func (f *ExampleFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
    var dynValues []types.Dynamic

    resp.Error = function.ConcatFuncErrors(resp.Error, req.Arguments.Get(ctx, &dynValues))
    if resp.Error != nil {
        return
    }

    for _, dynValue := range dynValues {
        if dynValue.IsNull() || dynValue.IsUnknown() {
            continue
        }
        // ... do something with argument value, i.e. dynValue.UnderlyingValue() ...
    }

    // ... other logic ...
}

```

In these Terraform configuration examples, the function variadic argument will receive the following value types:

```hcl
# []types.Dynamic{}
provider::example::example()

# []types.Dynamic{types.String}
provider::example::example("hello world")

# []types.Dynamic{types.Bool, types.Number}
provider::example::example(true, 1)

# []types.Dynamic{types.String, types.Tuple[types.String, types.String], types.List[types.String]}
provider::example::example("hello", ["one", "two"], tolist(["one", "two"]))
```
