liveBook · Manning

Validation

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

Validation is the process of checking configuration inputs against required formats, values, or dependencies before processing them.

An invalid input can turn a Terraform run into a misconfiguration—or produce an error only after a lengthy plan or apply. Validation checks inputs early and gives users a clear reason to correct them. A variable’s type constraint checks its type; custom validation adds rules such as length, format, or range. section 3.7 section 3.3.3

Add a `validation` subblock inside a `variable` block. Its `condition` must evaluate to true or false; if false, Terraform displays `error_message`. Use separate blocks when separate failures deserve distinct messages. For example, a number between 0 and 10 can have one rule for each bound and another to require an integer. section 3.7

Listing 3.30 Multiple validations
variable "my_integer" {
  description = "An integer between 0 and 10 inclusive."
  type        = number
 
  validation {                                              #1
    condition     = var.my_integer <= 10
    error_message = "The value must not be greater than 10."
  }
 
  validation {                                              #2
    condition     = var.my_integer >= 0
    error_message = "The value must not be less than 0."
  }
 
  validation {                                              #3
    condition     = can(parseint(tostring(var.my_integer), 10))
    error_message = "The value must be an integer."
  }
}

The three checks distinguish an excessive value, a negative value, and a non-integer value instead of reporting one generic failure. section 3.7

Validation can also protect resource arguments. An instance-count input should be a whole number and nonnegative before it reaches an `aws_instance` resource’s `count` argument. For rules involving multiple inputs, version matters: before Terraform 1.9.0, a variable’s validation could access only that variable; from 1.9, its condition can use almost any boolean expression, provided it includes the variable being tested. section 4.1.3 section 3.7

Provider configuration needs its own checks before creating a client. Values needed by a provider can still be unknown when Terraform configures it. Read each parameter, account for environment-variable defaults and provider-block overrides, and check applicable formats or dependencies. Add attribute-specific errors to diagnostics rather than stopping at the first failure; after processing the values, return if diagnostics contain errors. section 12.4.3

Listing 12.9 Provider configure attribute validation
func (p *MastodonProvider) Configure(ctx context.Context, req 
provider.ConfigureRequest, resp *provider.ConfigureResponse) {
    var data MastodonProviderModel
    tflog.Debug(ctx, "mastodon_provider configure")
    resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
 
    if data.Host.IsUnknown() {                                          #1
        resp.Diagnostics.AddAttributeError(
            path.Root("host"),                                          #2
            "Unknown Mastodon API Host",
            "The provider cannot create the Mastodon API client as there 
is an unknown configuration value for the Mastodon API host. "+
                "Either target apply the source of the value first, set 
the value statically in the configuration, or use the MASTODON_HOST 
environment variable.",
        )
    }
    host := os.Getenv("MASTODON_HOST")                                   #3
    if !data.Host.IsNull() {                                             #4
        host = data.Host.ValueString()
    }
    if host == "" {                                                      #5
        resp.Diagnostics.AddAttributeError(
            path.Root("mastodon-host"),                                  #6
            "Missing Mastodon Credentials",                              #7
            "The provider cannot create the Mastodon API client as the 
Host is not set.",                                                     #8
        )
    }
 
    /* client-id, client-secret, user-email, user-password, and 
user-access-token follow the same pattern */
    /* These blocks were excluded for brevity, but you should add them in 
if you're running this locally. */
 
    if access_token == "" && (user_email == "" || user_password == "") { #9
        resp.Diagnostics.AddAttributeError(
            path.Root("user-access-token"),
            "Missing Mastodon Credentials",
            "The provider cannot create the Mastodon API client as neither 
the Access Token or the Username and Password fields are set.",
        )
    }
 
    if resp.Diagnostics.HasError() {                                     #10
        return
    }
}
#1 If the variable is in the special “unknown” state, we can’t use it and need to register an error.
#2 We have to update our import statement to include github.com/hashicorp/terraform-plugin-framework/path.
#3 First load the value from environment variables. This will default to an empty string.
#4 Now if the value is set in the configuration, we’ll use that instead.
#5 If the value isn’t set anywhere we need to register an error.
#6 We should call out the specific attribute that is missing.
#7 This is the title of the error.
#8 This is the description of the error.
#9 Now we have to confirm that we have either the access token or the username and password.
#10 If we have any errors, we need to stop here. By waiting until the end we can collect all of the errors and present them to the user at once.

The provider configuration check attaches an error to the unknown `host` attribute and tells the user how to supply a usable value. section 12.4.3

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Explains variable conditions and error messages, then gives a provider procedure for collecting diagnostics before returning.
Examples
Uses integer-range checks, an instance-count input, and an unknown provider host to show distinct failures.
What it assumes
Builds on Terraform variable blocks and type constraints, with simple type examples available as groundwork.
What you can do after
Apply it via Terraform validation blocks and provider diagnostics to report actionable input errors before using configuration values.
How it connects
Connects validation to type constraints, Terraform variables, resource count, provider configuration, and diagnostics.

Also explained in

Compare how 30 books explain validation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.