Skip to content

Debugging

If you are running into issues with Terragrunt, join the Terragrunt Community Discord Server.

The easiest way to get more information for debugging an error you are experiencing in Terragrunt is to increase the log level.

Terminal window
terragrunt run --log-level debug -- plan

Increasing the log level using the --log-level flag will output more information about what Terragrunt is doing and why. This is useful information for your debugging, and for sharing with others if you want their help in understanding what went wrong in your run.

Terragrunt has a fairly sophisticated logging system, and it can be helpful to read through the documentation on Logging to understand how it works.

If you have Docker installed, and you want to gain deeper insight as to what Terragrunt is doing, you can also enable the OpenTelemetry integration in Terragrunt to send telemetry data to a locally running container to better visualize what Terragrunt is doing and when.

First, run the following in a terminal:

Terminal window
docker run --rm --name jaeger -e COLLECTOR_OTLP_ENABLED=true -p 16686:16686 -p 4317:4317 -p 4318:4318 jaegertracing/all-in-one:1.54.0

This spins up a local instance of Jaeger, which is a distributed tracing system that can be used to see what Terragrunt is doing.

Next, run the following in the terminal where you want to run Terragrunt:

Terminal window
export TG_TELEMETRY_TRACE_EXPORTER=http
export TG_TELEMETRY_TRACE_EXPORTER_HTTP_ENDPOINT=localhost:4318
export TG_TELEMETRY_TRACE_EXPORTER_INSECURE_ENDPOINT=true

This tells Terragrunt that it should send telemetry data to the Jaeger instance running in the Docker container.

Now you’ll want to do whatever you want to trace with Terragrunt by running Terragrunt normally.

Terminal window
terragrunt run -- plan

Finally, visit the Jaeger UI at http://localhost:16686 to see traces of your runs.

Terragrunt and OpenTofu/Terraform usually play well together in helping you write scalable, reusable infrastructure. But how can you figure out what went wrong in the rare case that things do go wrong?

Terragrunt provides a way to configure its logging level through the --log-level flag. Additionally, Terragrunt provides an --inputs-debug flag that can generate a terragrunt-debug.tfvars.json file to help you understand what inputs it is setting when calling OpenTofu/Terraform.

For example, you could use it like this to debug a plan that’s producing unexpected outcomes.

Terminal window
terragrunt run --log-level debug --inputs-debug -- plan

Running this command will do two things for you:

  • Output a file named terragrunt-debug.tfvars.json to your current working directory (the same one containing your terragrunt.hcl)
  • Print instructions on how to invoke tofu/terraform against the generated file to reproduce exactly the same tofu/terraform output as you saw when invoking terragrunt. This will help you to determine where the problem’s root cause lies.

Using those features is helpful when you want determine which of these three major areas is the root cause of your problem:

  1. Misconfiguration of your infrastructure code.
  2. An error in terragrunt.
  3. An error in tofu/terraform.

Consider this file structure for a fictional production environment where we have configured an application to deploy as many tasks as there are minimum number of machines in some cluster.

  • Directorylive
    • Directoryprod
      • Directoryapp
        • vars.tf
        • main.tf
        • outputs.tf
        • terragrunt.hcl
      • Directoryecs-cluster
        • outputs.tf

The files contain this text (app/main.tf and ecs-cluster/outputs.tf omitted for brevity):

app/vars.tf
variable "image_id" {
type = string
}
variable "num_tasks" {
type = number
}
# app/outputs.tf
output "task_ids" {
value = module.app_infra_module.task_ids
}
# app/terragrunt.hcl
locals {
image_id = "acme/myapp:1"
}
dependency "cluster" {
config_path = "../ecs-cluster"
}
inputs = {
image_id = locals.image_id
num_tasks = dependency.cluster.outputs.cluster_min_size
}

You perform a terragrunt plan, and find that outputs.task_ids has 7 elements, but you know that the cluster only has 4 VMs in it! What’s happening? Let’s figure it out. Run this:

Terminal window
terragrunt plan --log-level debug --inputs-debug

After planning, you will see output like this in stderr:

[terragrunt] Variables passed to tofu/terraform are located in "~/live/prod/app/terragrunt-debug.tfvars"
[terragrunt] Run this command to replicate how tofu/terraform was invoked:
[terragrunt] tofu plan -var-file="~/live/prod/app/terragrunt-debug.tfvars.json" "~/live/prod/app"

Well we may have to do all that, but first let’s just take a look at terragrunt-debug.tfvars.json

{
"image_id": "acme/myapp:1",
"num_tasks": 7
}

So this gives us the clue — we expected num_tasks to be 4, not 7! Looking into ecs-cluster/outputs.tf we see this text:

ecs-cluster/outputs.tf
output "cluster_min_size" {
value = module.my_cluster_module.cluster_max_size
}

Oops! It says max when it should be min. If we fix ecs-cluster/outputs.tf we should be golden!

If you’re still having trouble, you may want to try adjusting the TF_LOG environment variables to instruct OpenTofu/Terraform to emit more detailed logs.

Terminal window
TF_LOG=debug terragrunt run -- plan

You can learn more about OpenTofu/Terraform debug logging here.