How to Troubleshoot Terraform Errors

Understand the basics of debugging Terraform errors.

It's frustrating when your Terraform code doesn't work as expected. The good news is that Terraform provides powerful tools to help you pinpoint and fix issues. The key to effective debugging is to adopt a systematic approach, starting with the obvious and moving toward more detailed analysis.

Initial Troubleshooting Steps

Before diving into detailed logs, perform these quick checks to resolve common errors.

  • Read the Error Message: This is the most crucial step. Terraform's error messages are often very descriptive, pointing you to the exact line number and the nature of the problem, whether it's a syntax error, a missing argument, or a provider issue.
  • Run terraform validate: This command checks your configuration files for syntax and internal consistency without accessing any remote state or services. It's a quick way to catch typos and structural mistakes in your code.
  • Run terraform plan: This command is your "dry run." It generates an execution plan, showing you exactly what Terraform intends to create, modify, or destroy. This is invaluable for catching logical errors, such as a misconfigured dependency or an unexpected change to an existing resource.
  • Check Provider Credentials and Permissions: A common issue is a lack of permissions. Ensure that the credentials (e.g., access keys, IAM roles) you're using have the necessary permissions to create and manage the resources defined in your code.

Enable More Logging

When the initial steps don't provide enough information, it's time to enable Terraform's detailed logging. This feature gives you a granular look at what's happening under the hood.

To enable logging, you use the TF_LOG environment variable. You can set it to different levels of verbosity:

  • TRACE: This is the most verbose level, showing every internal action and interaction with provider plugins. Use this for deep, complex issues.
  • DEBUG: Provides a detailed log of provider and backend interactions. This is a great starting point for most complex debugging.
  • INFO: Logs high-level messages about the execution process.
  • WARN: Shows non-critical warnings.
  • ERROR: Only logs fatal errors.

To use it, simply prepend the variable to your Terraform command. For example, to run a plan with DEBUG logging:

export TF_LOG=DEBUG
terraform plan

The logs are often very long and can be hard to read in the terminal. To save them to a file for easier analysis, use the TF_LOG_PATH environment variable:

export TF_LOG=TRACE
export TF_LOG_PATH="terraform-debug.log"
terraform apply

Examining the Terraform State

The Terraform state file is a JSON document that maps the resources in your configuration to the real-world infrastructure. Inconsistencies or corruption in this file can lead to errors.

  • terraform state list: This command lists all the resources that Terraform is managing. It's a good way to verify that the state file is correctly tracking your infrastructure.
  • terraform state show <resource_address>: Use this to inspect the attributes of a specific resource in the state file. This can help you identify if a resource is in an unexpected state or has incorrect attributes.
  • terraform refresh: This command updates the state file to reflect the current state of your infrastructure. If a resource was manually changed outside of Terraform, terraform refresh can sync the state file.

Other Useful Commands and Techniques

The terraform console is an interactive command-line environment for evaluating expressions and testing logic. It's extremely useful for debugging variables, locals, and complex data structures.

terraform console

# Example: Check the value of a variable
> var.instance_type
"t2.micro"

# Example: Test a complex expression
> flatten([["a", "b"], ["c"]])
[ "a", "b", "c" ]