Validation
The framework can return diagnostics feedback for values in provider, resource, and data source configurations or errors feedback for values in function parameters. This allows you to write validations that give users feedback about required syntax, types, and acceptable values.
This page describes single attribute, parameter, and type validation concepts that can be used in any data source schema, provider schema, resource schema, or function definition. Further documentation is available for other configuration validation concepts:
- Data source validation for multiple attributes declaratively or imperatively.
- Provider validation for multiple attributes declaratively or imperatively.
- Resource validation for multiple attributes declaratively or imperatively.
- Ephemeral Resource validation for multiple attributes declaratively or imperatively.
Note: When implementing validation logic, configuration values may be unknown based on the source of the value. Implementations must account for this case, typically by returning early without returning new diagnostics.
During execution of the terraform validate
, terraform plan
, terraform apply
and terraform destroy
commands, Terraform calls the provider ValidateProviderConfig
, ValidateResourceConfig
, ValidateDataResourceConfig
, and ValidateEphemeralResourceConfig
RPCs.
Default Terraform CLI Validation
The Terraform configuration language is declarative and an implementation of HashiCorp Configuration Language (HCL). The Terraform CLI is responsible for reading and parsing configurations for validity, based on Terraform's concepts such as resource
blocks and associated syntax. The Terraform CLI automatically handles basic validation of value type and behavior information based on the provider, resource, or data source schema. For example, the Terraform CLI returns an error when a string value is given where a list value is expected and also when a required attribute is missing from a configuration.
Terraform CLI syntax and basic schema checks occur during the terraform apply
, terraform destroy
, terraform plan
, and terraform validate
commands. Any additional validation you define with the framework occurs directly after these checks are complete.
Attribute Validation
You can introduce validation on attributes using the generic framework-defined types such as types.String
. To do this, supply the Validators
field with a list of validations, and the framework will return diagnostics from all validators. For example:
All validators in the slice will always be run, regardless of whether previous validators returned an error or not.
Common Use Case Attribute Validators
You can implement attribute validators from the terraform-plugin-framework-validators Go module, which contains validation handling for many common use cases such as string contents and integer ranges.
Creating Attribute Validators
If there is not an attribute validator in terraform-plugin-framework-validators
that meets a specific use case, a provider-defined attribute validator can be created.
To create an attribute validator, you must implement at least one of the validator
package interfaces. For example:
Optionally and depending on the complexity, it may be desirable to also create a helper function to instantiate the validator. For example:
Path Based Attribute Validators
Attribute validators that need to accept paths to reference other attribute data should instead prefer path expressions. This allows consumers to use either absolute paths starting at the root of a schema, or relative paths based on the current attribute path where the validator is called.
Path expressions may represent one or more actual paths in the data. To find those paths, the process is called path matching. Depending on the actual data, a path match may return a parent path for null or unknown values, since any underlying paths of those null or unknown values would also represent the same value. This framework behavior is used to prevent false positives of returning no paths for null or unknown values.
The general structure for working with path expressions in an attribute validator is:
- Merge the given path expression(s) with the current attribute path expression, such as calling the request type
PathExpression
fieldMergeExpressions()
method. - Loop through each merged path expression to get the matching paths within the data, such as calling the request type
Config
fieldPathMatches()
method. - Loop through each matched path to get the generic
attr.Value
value, such as calling the request typeConfig
fieldGetAttribute()
method. - Perform null and unknown value checks on the
attr.Value
, such as theIsNull()
method andIsUnknown()
method. - If the
attr.Value
is not null and not unknown, then usetfsdk.ValueAs()
using the expected value implementation as the target.
The following example shows a generic path based attribute validator that returns an error if types.Int64
values at the given path expressions are less than the current attribute types.Int64
value.
Parameter Validation
You can introduce validation on function parameters using the generic framework-defined types such as types.String
. To do this, supply the Validators
field with a list of validations, and the framework will return errors from all validators. For example:
All validators in the slice will always be run, regardless of whether previous validators returned an error or not.
Creating Parameter Validators
To create a parameter validator, you must implement at least one of the function
package <Type>ParameterValidator
interfaces. For example:
Optionally and depending on the complexity, it may be desirable to also create a helper function to instantiate the validator. For example:
A single validator type can be used as both an attribute validator and a parameter validator, as long as the validator implements the appropriate interfaces. For example:
Value Validation
Validation of custom value types can be used for both attribute values and provider-defined function parameter values. This can be useful if you have consistent validation rules for a specific value type across multiple attributes or function parameters.
When you implement validation on a custom value type associated with a schema attribute, you do not need to declare the same validation on the attribute, but you can supply additional validations in that manner. For example:
Defining Value Validation
To support validation for a custom value type, you must implement xattr.ValidateableAttribute
interface for attribute validation, or function.ValidateableParameter
interface for provider-defined function parameter validation.
Both interfaces can be implemented if the same custom value type is used for both attributes and function parameters, for example:
Type Validation
Note
Value
validation should be used in preference to Type
validation. Refer to Value Validation for more information.
You may want to create a custom type to simplify schemas if your provider contains common attribute values with consistent validation rules. When you implement validation on a type, you do not need to declare the same validation on the attribute, but you can supply additional validations in that manner. For example:
Defining Type Validation
Note
The xattr.TypeWithValidate
interface has been deprecated. Refer to Defining Value Validation for more information about using xattr.ValidateableAttribute
interface, and function.ValidateableParameter
interface instead.
To support validation within a type, you must implement the xattr.TypeWithValidate
interface. For example: