Terraform

How to Debug & Troubleshoot Terraform Projects: Tutorial

47.debugging_terraform

Debugging and logging are the lifeline of developers when it comes to troubleshooting any kind of issue. If something has failed in a production environment, developers always look for the application logs which can give them the type, cause, and time of the error. 

The exact same principle is also followed when debugging the Terraform script. Terraform projects can grow very quickly when worked on by multiple teams. If you do not have a proper logging setup for troubleshooting, the project team will have a very difficult time troubleshooting and debugging.

In this article, we will focus on the commonly followed practices for debugging Terraform Projects. 

How to enable the logs for debugging? How to set the log file for debugging? How to manage log levels? Here’s how.

Prerequisite

The only prerequisite we have for this blog post is you must install Terraform on your host machine.

You can verify your Terraform installation by running the following Terraform version command:

$ terraform -version
Terraform v1.1.0
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v3.69.0

1. Set Log level using TF_LOG

There are certain log levels provided by Terraform for debugging and troubleshooting. As developers, we have to choose and set the log level for our Terraform project.

Types of Log Level

In total, there 5 log levels which can be used for debugging purposes:

  • TRACE—one of the most descriptive log levels, if you set the log level to TRACE, Terraform will write every action and step into the log file.
  • DEBUG—a little bit more sophisticated logging which is used by developers at critical or more complex pieces of code to reduce debugging time.
    1. INFO—the info log level is useful when needing to log some informative instructions or readme type instructions.
    2. WARN—used when something is not critical but would be nice to include in the form of a log so that the developer can make adjustments later.
  • ERROR—as the name suggests, this is used if something is terribly wrong and is a blocker.

How to set the log level?

The log level can be set with the environment variable TF_LOG. You need to export the variable with the correct log level. Here is an example of where TF_LOG is set with DEBUG level:

$ export TF_LOG=”DEBUG”

Verify the log level:

$ echo $TF_LOG
DEBUG

2. Set up log file using TF_LOG_PATH

After setting the log level, the next thing we need to set is the Log File Path, and for that we are going to use the environment variable TF_LOG_PATH.

For this blog post we are going to create a log file named terraform-debug.log.

We are going to place this file under the directory /home/vagrant/terraform-ec2-aws.

*Note – You can name and choose the log file path as per your requirement.

Let’s export the TF_LOG_PATH

export TF_LOG_PATH="/home/vagrant/terraform-ec2-aws/terraform-debug.log"

3. Verify the logs generated by Terraform

Now, after setting both Log Level and Log File path, let’s create a very small Terraform project to start an AWS EC2 instance.

Here is my main.tf:

resource "aws_instance" "ec2_example" {
 
  ami           = "ami-0767046d1677be5a0"
  instance_type = "t2.micro"
 
  tags = {
          Name = "Test  - Terraform EC2"
  }
}

Apply the above Terraform configuration by running the following commands: 

  1. terraform init
  2. terraform apply

After successful execution of the above Terraform code, let’s verify the debug logs available at /home/vagrant/terraform-ec2-aws/terraform-debug.log.

Here is the screenshot taken from the terraform-debug.log file which shows the DEBUG logs along with the INFO logs:

DEBUG logs and the INFO logs

Here are some sample logs from the terraform-debug.log:

2021-12-15T20:19:28.645Z [INFO]  Terraform version: 1.1.0
2021-12-15T20:19:28.645Z [INFO]  Go runtime version: go1.17.2
2021-12-15T20:19:28.645Z [INFO]  CLI args: []string{"terraform", "init"}
2021-12-15T20:19:28.645Z [DEBUG] Attempting to open CLI config file: /home/vagrant/.terraformrc
2021-12-15T20:19:28.645Z [DEBUG] File doesn't exist, but doesn't need to. Ignoring.
2021-12-15T20:19:28.645Z [DEBUG] ignoring non-existing provider search directory terraform.d/plugins
2021-12-15T20:19:28.645Z [DEBUG] ignoring non-existing provider search directory /home/vagrant/.terraform.d/plugins
2021-12-15T20:19:28.645Z [DEBUG] ignoring non-existing provider search directory /home/vagrant/.local/share/terraform/plugins
2021-12-15T20:19:28.645Z [DEBUG] ignoring non-existing provider search directory /usr/local/share/terraform/plugins

4. Using the error_message to validate variable value

Now that we have seen in the previous section on how to set up the TF_LOG and TF_LOG_PATH, let’s take a look at an example of how to put some custom validation on the Terraform variable, and to see if the validation fails. For this, we are going to log an error_message.

Validation condition: Provision of the EC2 instance should be restricted to t2.nano, t2.micro, t2.small. If the developer wants to provision the t2.medium or any other higher instance, we should restrict the developer with the proper error messages.

Here is a Terraform script with a validation and error_message:

resource "aws_instance" "ec2_example" {
 
  ami           = "ami-0767046d1677be5a0"
  instance_type =  var.instance_type
 
  tags = {
          Name = "Terraform EC2"
  }
}
 
 
variable "instance_type" {
  description = "Instance type t2.micro"
  type        = string
  default     = "t2.medium"
 
  validation {
   condition     = can(regex("^[Tt][2-3].(nano|micro|small)", var.instance_type))
   error_message = "Invalid Instance Type name. You can only choose - t2.nano,t2.micro,t2.small"
 }
}

If you look carefully into the variable resource:

  1. condition:  We have defined the regex to allow only – t2.nano, t2.micro, t2.small
  2. error_message: We have set up an error message stating “Invalid Instance Type name. You can only choose – t2.nano,t2.micro,t2.small

So, when the user tries to supply t2.medium then they should get the following error message:

error message

Key Points

This post is all about making yourself aware of the debugging and logging features provided by Terraform for troubleshooting the issues which you might face in your development, testing, staging, or production instances.

Setting up the correct info, debug and error message can significantly lessen your troubleshooting time as well as make your monitoring task. You can even dump the Terraform logs into log analyzer tools such as Splunk or ELK to get some visual graphs.

Terraform Management Made Easy

Spacelift effectively manages Terraform state, more complex workflows, supports policy as code, programmatic configuration, context sharing, drift detection, resource visualization and includes many more features.

Start free trial