# Speed Up Terraform Debugging Using Terraform Console

Want to debug terraform issues with quicker feedback and instant access to terraform state? Try ✨[Terraform Console](https://developer.hashicorp.com/terraform/cli/commands/console) ✨ - the equivalent of the python shell, but for Terraform.

# Background

> What am I doing?

This week I've been working on setting up canary analysis with Argo Rollouts for a service I'll refer to as: `my-service`. We do this by using Terraform and the *way* we do it requires having a local variable named `local.my-service_pools` containing a map of environments and their pools.

---

# The Problem

1. The pools (zones) that `my-service` runs in for each environment (`production`, `staging` and `meta`) are read from multiple yaml files and stored in a variable named `local.my-service_pools`
    
2. `local.my-service_pools` is used by other terraform tooling and therefore must be correct as soon as it's created.
    
3. Due to the way that our infrastructure is set up, the variable requires that any pool named `us-central1-f` be named `default`, and therefore any mention of `us-central1-f` would need to be swapped for default in this map.
    

To tackle this problem, I decided to first read the contents of the file into a temporary variable named `local.my-service_zonal_pools_from_yaml` which I *thought* simply looked like this:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686947037479/132b803d-774a-4f99-a958-39f58a8745ce.png align="center")

# The Goal

To create a new variable named `local.my-service_pools` which uses a `for` loop to iterate through my temporary `local.my-service.zonal_pools_from_yaml` and while doing so: replace any mention of `us-central1-f` with `default.`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686948079719/20d71744-7885-44c2-8f6f-0eff1b1f7a05.png align="center")

# A Failed Fix

I used a `for` loop to make a "copy" of the variable (Terraform doesn't support copying variables) by iterating through each environment, and then through each pool to replace `us-central1-f` with `default`

I referred to this as my *"transformation"* variable.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686946110352/b79ca755-76c8-44db-81f6-d9f6b6756de5.png align="center")

Which *seemed* good but... was actually **wrong ❌**, because the downstream references to that variable kept on yelling at me:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686946134668/dd51c571-e874-4267-9693-c6f11549e51f.png align="center")

# Frustration

1. **The error message doesn't tell me much.** Yes, it's a list of strings, but *that's what I wanted isn't it?*
    
2. **The Feedback loop is too long.** Because this is the Terraform for our entire environment's infrastructure and because our Terraform runner (Spacelift) is constantly running plans from PR's across the organization - I have to wait a **long** time to see the results of my changes via `terraform plan`
    
    1. On Spacelift, I'm competing with private workers to become available to run my plan; and
        
    2. On my laptop - it takes 10+ minutes to build because I don't have the state cached (or, more specifically, that the cache keeps on changing with every run on Spacelift.
        

# Research

I realized I was getting bitten on syntax / data massaging here - and first I'd need a better, faster, cheaper way to play with the Terraform for quick iteration and results.

And so off to Google I went.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686946709221/2463794d-a759-4237-827b-cbd1e859b651.jpeg align="center")

# Enter: [terraform console](https://developer.hashicorp.com/terraform/cli/commands/console)

> What does Terraform Console do? The terraform console command will read the Terraform configuration in the current working directory and the Terraform state file from the configured backend so that interpolations can be tested against both the values in the configuration and the state file.

With `terraform console`

1. I could see the warning I was running into as soon as it started up. (It's my "early-warning" that the code was still incorrect)
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686946165253/c200bee8-aa4a-4550-a21d-b46111fedf37.png align="center")

1. I could inspect and see what `local.my-service_zonal_pools_from_yaml` actually looked like right now!
    
2. And then I could compare it against `local.my-service_pools` to see what my *transformation* variable instantiation was *actually* putting out!
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686947167884/98233967-deae-4fbc-8a6c-02b8434bf485.png align="center")

**‼️ The actual problem was** that: `my-service_pools_from_yaml` has each environments zones in a **toset()** whereas `my-service_pools` has those zones in a **tolist()**

# Solution

✨Surround the `for` loop with a `toset()`✨

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686946235500/789fea53-c693-4ac9-8d7e-8ad4c0137f2f.png align="center")

Now when I run terraform console there are no errors, which is my first-sign that my code is correct.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686947199830/70547594-193c-4282-adbf-606f22455773.png align="center")

And, when I compare the two variables in the console, I see that they are both `toset()`'s ✅:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686947095731/372f9554-25ff-4374-9340-fccde760cea3.png align="center")

## Caution

While you're in the console, you acquire a state lock 🔒 that could prevent other people from using Terraform.

```yaml
Releasing state lock. This may take a few moments...
```

> The console holds a [lock on the state](https://developer.hashicorp.com/terraform/language/state/locking), and you will not be able to use the console while performing other actions that modify state.

# Conclusion

In conclusion, [terraform console](https://developer.hashicorp.com/terraform/cli/commands/console) is a powerful tool for debugging and fine-tuning Terraform code, providing quick feedback and reducing the time spent waiting for `terraform plan` results. It is especially useful for working with loops, experimenting with new syntax, and resolving structural issues. However, be cautious when using the console as it acquires a state lock, which may prevent others from modifying the state.
