[Virtual Event] IaCConf 2026: Real stories on how infra teams are keeping pace

Register Now ➡️

Terraform

Terraform Validate Command – Validate Configuration Locally

terraform validate

The terraform validate command checks whether your Terraform configuration is syntactically valid and internally consistent. It runs entirely on your local machine, without contacting any provider APIs, reading state, or comparing against real infrastructure, which makes it the fastest way to catch typos, missing arguments, type mismatches, and broken references before you reach plan or apply

It does not validate variable values, provider credentials, or whether your configuration will actually succeed against a live environment.

In this article, we cover what terraform validate does, how it differs from plan and fmt, how to run it (including the -json and -no-color flags), and how to wire it into a CI/CD pipeline.

What we will cover:

  1. What is the terraform validate command?
  2. What issues are detected by terraform validate?
  3. Differences between plan and validate
  4. How to use the terraform validate command
  5. Examples: Running terraform validate

What is the terraform validate command?

The validate command in Terraform is used to verify the correctness of Terraform configuration files. It checks the syntax of the Terraform files, ensures the correct usage of attributes and values, and validates the configuration based on the core syntax of Terraform, and also by checking all the providers in the code. By using this command, developers can catch and solve configuration errors before attempting to apply changes to the infrastructure.

The terraform validate command is very useful in many cases, including:

  1. To be sure about the internal consistencies of the developed configuration before using external information like state and deployed resources.
  2. When we want to use the output of the validate command to pass this information to other applications.
  3. To catch syntax errors, misconfigurations, or unsupported arguments early in the development process, reducing the risk of deploying erroneous configurations.
  4. To ensure that modules and resource blocks follow best practices, which can help improve the maintainability and readability of the Terraform configuration.

Terraform validate syntax and command options

The syntax for the validate command:

terraform validate [options]

It has two options:

  1. -json – outputs the error details in JSON format. The output produced in JSON format is used as input to another program, which may trigger appropriate automation workflows or any associated program.
  2. -no-color – produces the output without any color.

What common issues are detected by terraform validate?

The terraform validate command checks for:

  • Syntax errors in .tf files.
  • Unsupported arguments, missing fields, and type mismatches.
  • Valid provider requirements
  • Misspelled argument names or typos.
  • Use of resources, data sources, or modules that are not correctly defined.
  • Missing or invalid variable types.
  • Incorrect nesting or closing of brackets.

One of the shortcomings of the validate command is that it cannot be used to perform custom validations defined on the input variables

One limitation of terraform validate is that it does not run custom validations defined on input variables. You can still attach validation conditions and error messages to your variables, but those rules are only evaluated when you run terraform plan or terraform apply, not during validate. So while input variable validation is useful for enforcing consistent configuration, it will not catch invalid values at the validate step.

Input variable validation offers guardrails for consistent configuration, but these conditions are not interpreted by the terraform validate command. These validation rules are validated during plan and apply.

What is the difference between terraform plan and validate?

If you have managed infrastructure using Terraform, then you must have used the plan and apply commands to execute the changes defined in the configuration files. As the name suggests, apply applies to the configuration, which means that once the apply command is executed, the changes begin to take effect.

We use the plan command to validate the changes that will be applied using the apply command. Terraform plan command helps us identify exactly which resources will be created, replaced, changed, or destroyed without actually executing them. Additionally, the output of the plan command can be saved and used during apply command.

Apart from validation, the output of the plan command is used to manage infrastructure in a targeted manner, using modes and various options. The plan, thus generated, is input to the apply command for this.

All the actions performed by the plan command use various API calls to the remote state files and cloud platform APIs because it needs to get the latest information on the state and real-world deployments.

The terraform plan command checks configuration changes against remote state and cloud resources, while terraform validate verifies syntax and internal consistency of the configuration on the host, without referencing external resources.

Thus, the validate command does not depend on any state file or information regarding deployed resources. You should use this command to validate the consistencies between reusable modules in a given Terraform configuration directory.

What is the difference between terraform fmt and validate?

terraform fmt is in charge of formatting your code to respect best practices (indentation, spacing, etc), while terraform validate tells you if your configuration is valid or not, without checking it against live infrastructure.

How to use the terraform validate command

Before you can run terraform validate, the working directory must be initialized. Validation depends on the providers and modules referenced in your configuration being available locally, which means terraform init has to run first:

terraform init
terraform validate

If you want to initialize without configuring a backend (useful in CI when you only care about validation), use:

terraform init -backend=false
terraform validate

Let’s consider different scenarios.

1. Basic usage

terraform validate operates on a directory, not on individual files. Run it from the root of the configuration you want to check:

terraform validate

Terraform automatically picks up every .tf and .tf.json file in that directory and validates them as a single configuration. There is no flag to point validate at a different directory or a single file. If you need to validate code that lives elsewhere, change into that directory first:

cd path/to/config
terraform validate

2. Validate a single file

Terraform does not support validating one file in isolation. The unit of validation is always the directory, because references between resources, variables, and locals can span multiple files. If you genuinely need to check a single file on its own, the only workaround is to place it in its own directory and run terraform init -backend=false followed by terraform validate.

In practice, this is rarely what you actually want. If you’re editing a file and want fast feedback, an editor extension backed by the official Terraform language server (terraform-ls) will surface syntax and semantic issues as you type, which is much faster than re-running validate

For formatting consistency, terraform fmt -check is the right tool.

3. Validate multiple configuration files

Terraform automatically validates all .tf and .tf.json files in the current directory in a single run, so no special command is needed for “multiple files.” From within your configuration directory, run:

terraform validate

If your configuration lives in a different directory, change into it first. Note that the directory must be initialized before validation, since terraform validate requires any referenced providers and modules to be installed:

cd /config_files_path
terraform init -backend=false   # only needed if not already initialized
terraform validate

The -backend=false flag lets you initialize without configuring a remote backend, which is useful for validation-only workflows (such as CI checks on reusable modules).

4. Validate command with module block

Modules are validated the same way as any other configuration. Change into the module directory, initialize it, and run validate:

cd modules/my-module
terraform init
terraform validate

This is the recommended workflow for module authors. Validating each module independently catches issues like missing variable declarations, unused outputs, and bad provider references that would otherwise only surface when the module is consumed somewhere else.

Exit codes

terraform validate returns an exit code you can use in scripts and CI pipelines:

  • 0 if no errors are detected (configuration is valid, possibly with warnings)
  • 1 if any errors are detected

Warnings on their own do not produce a non-zero exit code, so the command is safe to use as a gate in a CI workflow without extra parsing.

Examples: Running terraform validate

To understand the validate command usage, let us consider the Terraform configuration below. This creates a standalone EC2 instance. and uses a few input variables for AMI, instance type, and tag value.

// Standalone EC2 instance
resource "aws_instance" "my_vm" {
 ami           = var.ami //Ubuntu AMI
 instance_type = var.instance_type
 
 tags = {
   Name = var.name_tag,
 }
}
 
variable "ami" {
 type        = string
 description = "Ubuntu AMI ID in N. Virginia Region"
 default     = "ami-065deacbcaac64cf2"
}
 
variable "instance_type" {
 type        = string
 description = "Instance type"
 default     = "t2.micro"
}
 
variable "name_tag" {
 type        = string
 description = "Name of the EC2 instance"
 default     = "My EC2 Instance"
}

When we run terraform validate in the Terraform root directory, it simply outputs whether the configuration is valid or not. For a valid configuration, the output is shown below.

terraform valid configuration

However, if the configuration is invalid, it provides us with the details as shown in the screenshot below. I deliberately changed the reference to the variable “name_tag” to “nametag” to cause the error message below. The details include:

  1. File name
  2. Line of code that causes the error
  3. Summary of the error message
  4. Details
terraform invalid configuration

The details are very helpful since they are self-explanatory.

Run terraform validate with -no-color flag

Let’s use the -no-color flag and observe the output in success and error cases. If you compare the output below to the ones above, it does not contain any word which is highlighted using colors.

For example, “Success!” is not Green, and “Error:” is not Red.

terraform validate -no-color

Run terraform validate with -json flag

-json is an important flag as it is used to chain this output into another application or supply this information to any other integrated system. When we use this flag to run the validate command for a valid configuration, it produces the output below.

terraform validate -json

The JSON thus produced has a few attributes that describe the state of current validity of the Terraform configuration. The purpose of these attributes is detailed below:

  1. format_version – This is an attribute with a constant value of “1.0”. The value “1.0” indicates that the validity check is done against the compatibility promises made for Terraform v1.x.
  2. valid – A boolean value that indicates whether a given configuration is valid (true) or not (false). It is set as false when there is at least one validation error.
  3. error_count – Represents the number of errors identified in the given configuration during validation. Since there are no validation errors in the given configuration the value is set to 0.
  4. warning_count – This represents the number of warnings issued during the validate command run. Warnings do not invalidate the configuration, the “valid” flag is not set to false only for warnings. However, it represents the fact that the developers may have to resolve these warnings in the future.
  5. diagnostics – The diagnostics attribute is an array of nested JSON objects. Each object in this array includes the details of all the errors produced during a Terraform validate command run. To understand the details, let us break our Terraform configuration again, and observe the JSON output as below.
terraform validate -json attributes

When the Terraform configuration is invalid, the JSON output thus produced is represented in the screenshot above. As we can see, the valid attribute is set to false, error_count is 1, and there are no warnings.

The details of the error are included in the diagnostics array of nested JSON objects. Each object has attributes that provide more details. These attributes are described below:

  1. severity – Indicates if this is an error or a warning.
  2. summary – A short summary of the error. This is useful to indicate the kind of error that was encountered. In this case, it indicates that an error occurred when referencing the undeclared input variable. This is expected because we changed the variable reference from name_tag to nametag in our config.
  3. detail – This attribute provides deeper textual details about the error. It also includes the referencing variable names and gives us more clarity about what is broken in the configuration. It also suggests if we meant to use a certain value. This is useful to address typos. However, if the mistyped referencing variable name is not close to any given input variable name, it would not suggest this fix. For example, if instead of changing name_tag to nametag, I change it to “tag_name_mistake”, then the difference in the output of the detail attribute can be seen here.
tag name mistake output
  1. range – This attribute is assigned a JSON object that helps us pinpoint the error in the configuration. It includes a filename that points to a file that causes this error. The start and end attributes define the line, column, and even the byte information of the origin of this validation error. By the nature of it, we can already see this information can be a crucial asset when we have further automated processing to be done.
  2. snippet – The snippet attribute contains more details about the code snippet in consideration. As compared to the range details, this is more human-readable and keeps certain values ready for producing a generic human-readable output.

As mentioned before, using -json flag option enables us to pass this information in a machine-readable format to other systems. As an example, we need not look anywhere else but simply compare the output of terraform validate and terraform validate -json.

terraform validate output

Each word in the output above is created, formatted, and assembled based on the details present in the diagnostic attribute of the JSON output.

Run terraform validate for modules

Running terraform validate for modules is not too different from running it on a base configuration. You should go to your module’s root directory and simply run: terraform validate.

This will ensure that your module’s syntax is correct.

Run terraform validate in CI/CD workflow

If you are using a generic CI/CD, you can easily integrate the validation step, before running a terraform plan. A simplified workflow can look like this:

  • Checkout repo code
  • Install terraform
  • Run terraform init
  • [Optional] Run terraform fmt
  • Run terraform validate
  • Run terraform plan or terraform apply depending on what you want to achieve

IaC and immutable infrastructure are really important concepts to Kin. They chose Terraform as their platform, and very quickly adopted a full-blown GitOps workflow. When you shift to treating infrastructure like a software project, you need all of the same components that a software project would have. That means having a CI/CD platform in place, and most aren’t suited to the demands of IaC. Kin discovered that Spacelift was purpose-built to fill that gap.

Spacelift customer case study

Read the full story

Conclusion

In this article, we learned how to use the Terraform validate command and saw how -no-color and -json flags change the output.

Terraform is really powerful, but to achieve an end-to-end secure GitOps approach, you need a platform that can orchestrate your infrastructure workflows. Spacelift is the infrastructure orchestration platform built for the AI-accelerated software era. It manages the full lifecycle for both traditional infrastructure as code and AI-provisioned infrastructure, giving you access to features such as:

  • Policies (based on Open Policy Agent)
  • Multi-IaC workflows (Terraform, OpenTofu, CloudFormation, Pulumi, Ansible, and Kubernetes)
  • Self-service infrastructure via Blueprints and Templates
  • AI-powered provisioning, diagnostics, and operational insight with Spacelift Intelligence
  • Integrations with any third-party tools

If you want to learn more about Spacelift, create a free account today or book a demo with one of our engineers.

Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.

Manage Terraform better with Spacelift

Build more complex workflows based on Terraform using policy as code, programmatic configuration, context sharing, drift detection, resource visualization and many more.

Start free trial

Frequently asked questions

  • Does terraform validate need init?

    Yes. Validation requires an initialized working directory so that referenced providers and modules are available, but you can use terraform init -backend=false to skip backend configuration while still installing plugins.

  • Does terraform validate require AWS credentials?

    No. The command performs static analysis of configuration files and does not call provider APIs, so AWS credentials are not needed even when the AWS provider is declared.

  • Can terraform validate run in a pipeline without a backend?

    Yes. Run terraform init -backend=false to install providers and modules without configuring the backend, then execute terraform validate, which is the standard pattern for lightweight pipeline checks.

Terraform Commands Cheat Sheet

Grab our ultimate cheat sheet PDF
for all the Terraform commands
and concepts you need.

Share your data and download the cheat sheet