Background image

Terraform

Enhancing Terraform Providers with Configuration Validation

Ash Godfrey

Ash Godfrey

July 24, 2024

Featured blog post image

When working with APIs, ensuring that the values we send meet specific requirements, such as string lengths or numerical ranges, is crucial. This validation becomes even more critical when using Terraform Providers to interact with these APIs. Relying only on server-side validation can lead to slow feedback loops, errors during the apply phase, and frustrated users. Plan validation in Terraform Providers helps catch these issues earlier, improving the end-user experience by providing immediate feedback and preventing errors before they occur. This blog post explores how you can add configuration validation to your Terraform Providers.

The Problem with Missing Validation

APIs often enforce strict value requirements, such as minimum and maximum string lengths, numerical ranges, or specific formats. When a Terraform Provider interacts with an API but lacks validation for these requirements, Terraform’s validate and plan operations may proceed without issues. However, the apply operation can fail due to API errors, leading to frustrating and time-consuming feedback loops. These failures can occur in the middle of applying resources, causing further complications and delays.

Imagine you’re deploying multiple resources, and halfway through the process, an API error occurs because of an invalid string length. You would need to fix the issue and rerun the apply operation, wasting valuable time and resources. The goal is to enhance the user experience by having Terraform raise validation errors before applying configurations, ensuring smoother deployments and reducing the risk of mid-apply failures.

Why Does It Matter?

  • Efficiency: Early error detection saves time and resources by preventing mid-apply failures.
  • User Experience: Immediate feedback during validation enhances satisfaction and reduces frustration.
  • Resource Management: Preventing mid-apply failures ensures infrastructure remains stable and consistent.
  • Scalability: Early validation maintains a reliable deployment process as infrastructure grows.
  • Error Reduction: Automating validation reduces the risk of human error and ensures consistent application of validation rules.

Manual Validation in Terraform Providers

Adding validation to Terraform Providers involves implementing validators (opens in a new tab) within the resource schema.

Let’s assume you are developing a Terraform provider for managing a simple resource, such as a “User” resource, which has a “username” attribute:

func NewUserResource() resource.Resource {
return &userResource{}
}
type userResource struct{}
func (r *userResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_user"
}
func (r *userResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"username": stringattribute.String{
Required: true,
Description: "The username of the user.",
Validators: []validator.String{
stringvalidator.LengthBetween(6, 64),
stringvalidator.RegexMatches(
regexp.MustCompile(`^[a-z]+$`),
"must contain only lowercase alphanumeric characters",
),
},
},
},
}
}
  • The username attribute is defined with type schema.TypeString and marked as required.
  • The username attribute is defined with string validation helpers from terraform-plugin-framework-validators (opens in a new tab) that checks if the length of the string is between 6 and 64 characters, as well as only lowercase characters.

Consider the following configuration:

resource "user" "test" {
username = "abcd"
}

Running terraform validate will produce an error if the username length does not meet the specified criteria:

- Error: Invalid value for field "username": String length must be between 6 and 64 characters.
- Error: Invalid value for field "username": must contain only lowercase alphabetic characters.

See more in the terraform-plugin-framework-validators package here (opens in a new tab).

Repeating this process for every field in your Terraform Provider is daunting, but necessary to enhance the user experience by catching errors early in the validation phase, preventing issues during the apply phase, and ensuring smoother deployments.

Configuration Validation with Speakeasy

Speakeasy simplifies the process of adding configuration validation to Terraform Providers by automatically generating validation handlers based on your OpenAPI specification.

By default, these OpenAPI specification properties are automatically handled:

  • For string types: enum, maxLength,minLength, and pattern
  • For integer types: enum, minimum and maximum
  • For array types: maxItemsminItems, and uniqueItems

For scenarios not covered by these default handlers, Speakeasy supports custom validation logic. If you’re interested in finding out more, see our Terraform Provider generation documentation (opens in a new tab) and join our Slack (opens in a new tab) to chat with our engineering team.

Conclusion: Enhancing Terraform Providers with Validation

Adding configuration validation to Terraform Providers is essential for improving the end user experience and ensuring smooth deployments. By implementing validation, whether manually or through generated providers like those created by Speakeasy, developers can ensure consistent, efficient, and reliable configurations, ultimately benefiting API consumers. With robust validation in place, the risk of errors is minimized, leading to more stable and predictable infrastructure management.

CTA background illustrations

Speakeasy Changelog

Subscribe to stay up-to-date on Speakeasy news and feature releases.