Using the terraform console to debug interpolation syntax

I am a long time Terraform user. The number of providers that are available for Terraform, and having a resource for pretty much every cloud service makes it super appealing. But even with several years of production usage, I still find myself scratching my head at times when I’m writing my interpolations. Terraform provides a really nice shell to assist with this, and it can be accessed with the terraform “console” option:

$ terraform console

Once you are in the shell, typing an expression will produce immediate feedback:

> list("a","b","c")[0]
> a

The expression above creates a list, and then displays the first element in it. A more realistic example would be grabbing a given subnet from a list:

> aws_subnet.vpc-foo-public-subnets-proxies.*.id[0]

In this example I use the splat operator to get all subnets in a list, and then display the subnet in index 0. The console is also super useful for playing with data sources. To see what a data source contains, you can type it into the console:

> data.aws_availability_zones.available
  "group_names" = [
  "id" = "2020-04-26 14:08:51.531061491 +0000 UTC"
  "names" = [
  "state" = "available"
  "zone_ids" = [

Once you see the structure (maps, lists, strings etc.), you can use the built-in functions to massauge the data to your liking:

> slice(data.aws_availability_zones.available.names,2,4)

One other super useful feature is the ability to play with maps. You can retrieve map values:

> lookup(map("a","avalue","b","bvalue"), "a")

Or the keys that comprise a map:

> keys(map("a","avalue","b","bvalue"))

Or both the keys and their values:

> { for k, v in map("a", "one", "b", "two"): v => k }
> {
>   "one" = "a"
>   "two" = "b"
> }

As of Terraform 0.12, you now have the ability to use for, for_each and logic operators ( x ? y : z existed previously) in your HCL. Testing logic operations in the console is as easy as:

> keys(map("a","avalue","b","bvalue"))[0] == "a" ? "true" : "false"

> keys(map("a","avalue","b","bvalue"))[0] == "ab" ? "true" : "false"

The same goes for testing looping logic:

> [for string in ["one", "two", "three"] : upper(string)]

> [ for key in keys(map("a", "one", "b", "two")) : key ]
> [ for value in map("a", "one", "b", "two") : value ]

The console has become my best friend when writing Terraform code. I can test my code in the shell, then commit it once I know it will produce the result I want. This also reduces the number of times I need to come back to my code after reviewing my terraform plans. Viva la Terraform!

This article was posted by on 2020-04-27 00:00:00 -0500 -0500