Terraform Validate Command: Practical Examples and Best Practices
Tags: terraform, cloud, devops, infrastructureascode
Published: 2024-07-02 12:46:17

What is Terraform Validate
--------------------------

The `validate` command helps you make sure your [Terraform](https://www.env0.com/blog/what-is-terraform-cli) (or [OpenTofu](https://www.env0.com/blog/opentofu-the-open-source-terraform-alternative)) code is syntactically correct before you deploy. This helps you to prevent misconfiguration due to missing attributes or incorrect dependencies, saving time, improving efficiency, and reducing cost.

Under the hood, `terraform validate` performs these actions:

*   **Validates that the syntax of the terraform files is correct -** For example, if you want to use the terraform ternary function in your code and provide the incorrect syntax halfway, terraform can capture it and help you fix it.
*   **Verifies the consistency of the terraform configuration** -For instance, whether the value of the terraform variable matches the validation block defined for that variable. 
*   **Performs static analysis of the configuration file** -  For example, it checks whether all required fields for a resource are provided without accessing remote modules or the current state of infrastructure (without accessing any external network).

In this post, we will cover the following:

1.  How is the `terraform validate` useful
2.  How should you validate different file types - single file, multiple files, or modules
3.  What are the different ways you can run `terraform validate` locally
4.  How can you use env0 to run `terraform validate`

> **Disclaimer  
> ‍**All use cases of 'terraform validate' discussed here work similarly in OpenTofu, the open-source Terraform alternative. However, to keep thing simple and familiar, we will refer to 'terraform validate' throughout this discussion from now on.

**How to use Terraform Validate** 
----------------------------------

You can run `terraform validate` within a directory that contains a single configuration file, multiple configuration files, or modules at different stages of your infrastructure development. 

Let us do a hands-on demonstration to see how different running the `terraform validate` for each scenario can be.

### **Run Terraform Validate Locally for Multiple Files**

We will create a bucket in the Google Cloud Platform (GCP) using the Terraform configuration.  

Download the Google Cloud CLI on your machine and configure your directory to use the GCP project. Run this command in your terminal for the current working directory:

     gcloud config set project validate-project-425602

Set your provider in the **provider.tf** file with the project name.

    provider "google" {
      project = "validate-project-425602"
    }

In the **main. tf** file, create a bucket with the default configuration. To create a unique bucket name, we will create and pass the random ID using the random\_id resource block:

    resource "random_id" "bucket_id" {
      byte_length = 4
    }
    
    resource "google_storage_bucket" "bucket" {
      name          = "bucket_${random_id.bucket_id.hex}"
      storage_class = "STANDARD"
      labels = {
        name = "nonprod-bucket"
        team        = "engineering"
      }
    }
    

Go to the current working directory in your terminal and run the `terraform validate` command. 

You will catch syntax errors in your configuration files before deploying your infrastructure. This will save you time and prevent you from messing up your infrastructure on cloud platforms like Azure, AWS, and GCP.

If you have this bucket as a dependency, Terraform might attempt to create resources in the wrong order, leading to errors or incomplete infrastructure setups.

As an output, you will get the missing argument error message: 

![](https://cdn.prod.website-files.com/63eb9bf7fa9e2724829607c1/6682c2b5da77cfd74ecbe006_AD_4nXeoPOaLbE9dH3LHdfcu00JXqjhgtZ3i1W5ZhGEyItRhH_muL0HcBWubV95znqiHU4OrvETWLOBapsfUQzcGnaT90Xa9CVhO4CVZA6yv5QtSMdPLNNeP9IdG3_sQeLEQ6wzwsN_OPRAhwRxf6mgDdc_qxJc5.png)

You need to fix this error by adding the location to your `google_storage_bucket` resource and run `terraform validate` again.

If you do not add the location and try to deploy the bucket, it will fail with the same error message or lead to resource misconfigurations during deployment.

Once you have added the location, the output will display that the configuration is valid:

![](https://cdn.prod.website-files.com/63eb9bf7fa9e2724829607c1/6682c2b53024dc5fac17ebfa_AD_4nXdPUlSOrahIjW0aBBAVM_u3LicJvUgwyAkdivSO-r03YDwdtp3lC1vh1L76cGOCR6JeskuKhtJcGWfD7A2-mLaeybeXsAiMHVOTzCBuTG42HCk5vLQpcIrKgHZdAnmt4iBb3oMp0RiVr2UKGn65vEJnDBox.png)

Use of Flags in Terraform Validate
----------------------------------

You can use flags to help improve the output of `terraform validate`. Here are some instances of how you can use these in the above example. 

*   **\-json** flag: Produces output in a machine-readable JSON format without color. It is useful in text editor integrations. The diagnostics array of nested JSON objects provides more details of the errors, which will help you identify exactly where you can find the particular error in your code.

![](https://cdn.prod.website-files.com/63eb9bf7fa9e2724829607c1/6682c2b529510042b2c7db01_AD_4nXeXiphnDy77d6L0JiMc2CZLUV9hT5zQnSz7vIoUYrzEynHexxZz-fLd9z5RBnKeRGvSoSAaV2C3v156sVF_oeYTlrz9KkQYM7IXFg36A-yAMssNb5trAIVnAP1aQVZKlND_N8qPphEa6Ev2llDyGhVszrEz.png)

*   **\-no-color** flag: Disables the color output in the terminal. It is useful when the output is piped to another command or written to a file where color codes are inappropriate or difficult to read. 

![](https://cdn.prod.website-files.com/63eb9bf7fa9e2724829607c1/6682c2b5bd1c28da0a5a7fec_AD_4nXc2Q2Dj0zrXenPT0z8nmi-hvDexUzUbDV0MZRwAdWNaJfwCvkpGz_JXjFR_Hm_HMbRNJ6DpqXTH0wAuWAMbsrVTrLAJVltP4oHo0JNO9qGKgxPa4G5QD6FEZ_TktO_10WLGXw2neUHVZSgdrXht_JavKZZ2.png)

**Potential Issues Solved by Terraform Validate**
-------------------------------------------------

Let us look at the few scenarios taken care of by the `terraform validate` command:

*   It checks if the variable interpolation is correct and consistent with HCL.
*   It analyzes if the data passed to an attribute matches its desired data type.
*   It runs checks to verify if all the mandatory attributes are present for the resource or data block.
*    If you have [input variables](https://www.env0.com/blog/terraform-variables) declared by setting default values and custom validation rules and handling undeclared variables in Terraform configurations, they are validated against the multiple validation blocks.

**Practical Examples**
----------------------

Now that we have defined the basics for `terraform validate`, let's review some of the more advanced ways in which the command can be used:

#### **Running Terraform Validate as a Pre-Commit Hook for a Single File**

You might have all your configurations in one **main.tf** file and want to ensure that you do not push any syntactically incorrect code to a version control system like git.

To do this, you can run `terraform validate` as a pre-commit hook.

Configure your pre-commit hook by creating a **pre-commit** file in the **.github/hooks** folder of your project to run `terraform init` and `terraform validate`.

You will get an error if the configuration is invalid. The code for the pre-commit hook file looks like this: 

    #!/bin/bash
    TERRAFORM_DIR="path/to/your/terraform/directory"
    cd "$TERRAFORM_DIR" || exit 1
    terraform init -backend=false -input=false
    terraform validate
    EXIT_CODE=$?
    if [ $EXIT_CODE -ne 0 ]; then
        echo "Terraform validation failed. Please fix the issues and try again."
        exit $EXIT_CODE
    fi
    exit 0
    

Make this file executable by running this command in your current working directory:

    chmod +x .git/hooks/pre-commit

The pre-commit script will run when you make changes to the **main.tf** file and create a commit.

The Terraform configuration in your **main.tf** file will be validated, and you will get the following output:

![](https://cdn.prod.website-files.com/63eb9bf7fa9e2724829607c1/6682c350240d577173e1bb70_AD_4nXevdZ_RvceZONFIoA9wcrNO5yyajhh_Go-BbAr6Chn8WGvyvfmd7ll9gmUxYxyraZiHm9frCvanZ5WfDtlak0gxIuyBbe1HUqfljROVU_QW--Ban9jaciSjeyuMYHI71k85Bruv0muKfjbPIrz21xGXvXk.png)

#### **Running Terraform Validate for Modules**

To validate the [Terraform module](https://www.env0.com/blog/terraform-modules) configuration, navigate to the module directory and run `terraform validate`. 

For example, if a module named `iam-role` is configured incorrectly when `terraform validate` is run in the terminal inside the module, it will output an error message like the one below:

![](https://cdn.prod.website-files.com/63eb9bf7fa9e2724829607c1/6682c35081cbea403b9f2a64_AD_4nXcT4iHoD47bG8kMgs27H3UOPf9S8jEe5uaZzaDwWzk_Rwr-_N94Jrk5Llkp3S4ppwLssPQxrpU9VzoPBDtJnW955dny-YSm9sEYDFoXQohIgpDoTQ9xUwfciAwrk3QYU5ixPLd3-ZUi7DDboz9LXpaJThM.png)

If you do not fix this issue, Terraform may fail to apply the module configurations correctly, leading to incomplete or incorrect resource setups in your infrastructure.

#### **Running the Validate Command in a Workflow**

The infrastructure code with syntax errors is unreliable and inconsistent, causing deployment issues.

Running `terraform validate` frequently is essential during and after the initial stages of development. It will help prevent any syntax errors and allow you to get a valid configuration. 

When you run `terraform validate` locally, sometimes, you might forget to run the `terraform validate` command locally with frequent changes.

When that happens, you must include it as part of the CI/CD pipelines to achieve uniformity. 

You should make this a standard practice in your team or organization by using [env0](https://www.env0.com/) to run `terraform validate` as part of your CI/CD pipeline.

This will give you a consistent, easily scalable environment across multiple projects and team members, centralize and streamline workflows, and enhance compliance and audibility.

**Integrating Terraform Validation with env0**
----------------------------------------------

With [env0](https://www.env0.com/)’s [ad-hoc tasks](https://www.env0.com/blog/ad-hoc-tasks) feature, every Terraform command is tracked, allowing your team to see who ran the `terraform validation` command and when it was executed. 

One way this feature can be used is to automatically run `terraform validate` as part of your CI/CD pipeline, ensuring all Terraform configurations are syntactically correct before deployment. 

By integrating it with VCS, env0 allows multiple team members to collaborate on Terraform configurations, with automatic validation to catch errors early.

For example, here is how you can use env0’s ad-hoc feature to create a Storage Bucket from GCP into our Terraform configuration to streamline the validation process. 

First, push the Terraform configuration files to the GitHub repository, where you will create a storage bucket resource:

    resource "google_storage_bucket" "bucket-name" {
      name          = "bucket_${random_id.bucket_id.hex}"
      location      = "US"
      storage_class = "STANDARD"
      labels = {
        name = "prod-bucket"
      }
    }
    

Next, integrate this GitHub repository with [env0](https://www.env0.com/). For that, simply add a `terraform validate` command to your env0 workflow as an ad-hoc task:

![env0](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jkl3p3f6h9x6sbq64oan.png)

In the [env0](https://www.env0.com/) console you will see the task running with the output:

![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjv1ul7b91n23zs3u8ph.png)

And that's it! You have successfully validated your Terraform configuration for the GCP bucket, allowing you to auto-run syntax checks and validation within env0, as part of your CI/CD pipeline.

‍**Wrapping up**
----------------

The `Terraform validate` command is your go-to tool for ensuring your Terraform configurations are correct and consistent before deployment.

Whether running `terraform validate` locally or integrating it into your CI/CD pipelines with env0, `terraform validate` helps you get early feedback and save time.

Including `terraform validate` with [`terraform plan`](https://www.env0.com/blog/terraform-plan) and [`terraform apply`](https://www.env0.com/blog/terraform-apply-guide-command-options-and-examples) in your env0 workflows makes your processes reliable, efficient, and scalable.

**FAQ’s**
---------

#### **Q: What is the difference between terraform validate and terraform fmt?**

The two Terraform commands – `terraform validate` and `terraform fmt` – are used to maintain a clean, error-free, and well-structured Terraform codebase.

Let's quickly compare the two here:

![terraform validate vs terraform fmt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ougscs4y8uxwemfkxwke.png)

#### **Q: How do you validate variables in Terraform?**

Using the validation argument, you can define constraints within the variable block. This allows you to specify custom conditions that the variable values must meet.

#### **Q: How do you validate a Terraform file?**

You can use `terraform validate` to validate a Terraform file.

#### **Q: How do I validate the Terraform module?**

You should run `terraform validate` in the module path to validate a Terraform module.