Terraform Validate Command: Practical Examples and Best Practices

env0team

env0 Team

Posted on July 2, 2024

Terraform Validate Command: Practical Examples and Best Practices

What is Terraform Validate

The validate command helps you make sure your Terraform (or OpenTofu) 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
Enter fullscreen mode Exit fullscreen mode

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

provider "google" {
  project = "validate-project-425602"
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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: 

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:

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.

  • -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. 

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 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
Enter fullscreen mode Exit fullscreen mode

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

chmod +x .git/hooks/pre-commit
Enter fullscreen mode Exit fullscreen mode

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:

Running Terraform Validate for Modules

To validate the Terraform module 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:

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 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’s 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"
  }
}
Enter fullscreen mode Exit fullscreen mode

Next, integrate this GitHub repository with env0. For that, simply add a terraform validate command to your env0 workflow as an ad-hoc task:

env0

In the env0 console you will see the task running with the output:

output

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 and terraform apply 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

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.

💖 💪 🙅 🚩
env0team
env0 Team

Posted on July 2, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related