Terraform
Validate list resource configurations
List resource supports validating the entire practitioner configuration in either declarative or imperative ways. Feedback such as required syntax or acceptable combination of values, is returned via diagnostics.
This section describes implementation details for validating entire list configurations, typically referencing multiple attributes.
Further documentation is available for other configuration validation concepts:
- Single attribute validation is a schema-based mechanism for implementing attribute-specific validation logic.
- Type validation is a schema-based mechanism for implementing reusable validation logic for any attribute using the type.
Configuration validation in Terraform occurs without provider configuration ("offline"), therefore the list resource Configure method will not have been called.
ConfigValidators Method
The list.ListResourceWithConfigValidators interface follows a similar pattern to attribute validation and allows for a more declarative approach.
This enables consistent validation logic across multiple list resources. Each validation intended for this interface must implement the list.ConfigValidator interface.
The terraform-plugin-framework-validators Go module has a collection of common use case list configuration validators in the listresourcevalidator package.
These use path expressions for matching attributes.
This example will raise an error if a practitioner attempts to configure both attribute_one and attribute_two:
// Other methods to implement the list.ListResource interface are omitted for brevity
type ThingListResource struct {}
func (r ThingListResource) ConfigValidators(ctx context.Context) []list.ConfigValidator {
return []list.ConfigValidator{
listvalidator.Conflicting(
path.MatchRoot("attribute_one"),
path.MatchRoot("attribute_two"),
),
}
}
ValidateConfig Method
The list.ListResourceWithValidateConfig interface allows for imperative validation logic and is useful for validating unique functionality across multiple attributes that typically applies to a single list resource.
// Other methods to implement the list.ListResource interface are omitted for brevity
type ThingListResource struct {}
type ThingListResourceModel struct {
AttributeOne types.String `tfsdk:"attribute_one"`
AttributeTwo types.String `tfsdk:"attribute_two"`
}
func (r ThingListResource) ValidateConfig(ctx context.Context, req list.ValidateConfigRequest, resp *list.ValidateConfigResponse) {
var data ThingListResourceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
// If attribute_one is not configured, return without warning.
if data.AttributeOne.IsNull() || data.AttributeOne.IsUnknown() {
return
}
// If attribute_two is not null, return without warning.
if !data.AttributeTwo.IsNull() {
return
}
resp.Diagnostics.AddAttributeWarning(
path.Root("attribute_two"),
"Missing Attribute Configuration",
"Expected attribute_two to be configured with attribute_one. "+
"The list resource may return unexpected results.",
)
}