Terraform
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, as no type conversion will be performed to incoming argument data.
Refer to Dynamic Data - Considerations for more information.
Dynamic function parameters can receive any value type from a practitioner configuration. Values are accessible in function logic by the framework dynamic type.
In this Terraform configuration example, a dynamic parameter is set to the boolean value true
:
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
:
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
:
provider::example::example({
attr1 = "value1",
attr2 = 123,
})
Function Definition
Use the function.DynamicParameter
type in the function definition to accept a dynamic value.
In this example, a function definition includes a first position dynamic parameter:
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 or within collection parameter types.
If the dynamic value should be a value type of an object parameter type, set the AttributeTypes
map value according to the framework dynamic type. Refer to the object parameter type documentation for additional details.
Allow Null Values
Tip
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.
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 for further details on creating provider-defined types and values.
Documentation
Refer to function documentation for information about the Name
, Description
, and MarkdownDescription
fields available.
Reading Argument Data
The function 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.
In this example, a function defines a single dynamic parameter and accesses its argument value:
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 documentation.
Using Dynamic as a Variadic Parameter
Utilizing function.DynamicParameter
in the VariadicParameter
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
or []types.Dynamic
when reading a dynamic variadic argument.
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:
# []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"]))