terraform console
terraform console opens an interactive REPL (Read-Eval-Print Loop) where you can evaluate HCL expressions, test built-in functions, inspect variables, and query the current state — all without modifying anything. It’s Terraform’s built-in debugging tool.
Opening the Console
terraform consoleThe console loads the current working directory’s configuration and state. You’ll see a > prompt where you can type expressions.
$ terraform console>Exit with Ctrl+C or type exit.
Testing Built-in Functions
The console is the fastest way to verify function behavior before embedding it in configuration:
# String functions> upper("hello world")"HELLO WORLD"
> replace("hello-world-2025", "-", "_")"hello_world_2025"
> format("%-20s %5d", "resource-name", 42)"resource-name 42"
> trimspace(" padded string ")"padded string"
> split(",", "us-east-1,us-west-2,eu-west-1")tolist([ "us-east-1", "us-west-2", "eu-west-1",])# Numeric functions> max(10, 20, 5, 30, 15)30
> min(10, 20, 5)5
> ceil(2.1)3
> floor(2.9)2
> abs(-42)42# List and collection functions> length(["a", "b", "c", "d"])4
> contains(["dev", "staging", "prod"], "prod")true
> distinct(["a", "b", "a", "c", "b"])tolist([ "a", "b", "c",])
> flatten([["a", "b"], ["c"], ["d", "e"]])tolist([ "a", "b", "c", "d", "e",])
> index(["a", "b", "c"], "b")1CIDR and Networking Functions
Essential for infrastructure engineers working with VPC design:
> cidrsubnet("10.0.0.0/16", 8, 0)"10.0.0.0/24"
> cidrsubnet("10.0.0.0/16", 8, 1)"10.0.1.0/24"
> cidrsubnet("10.0.0.0/16", 8, 255)"10.0.255.0/24"
# Generate multiple subnets> [for i in range(4) : cidrsubnet("10.0.0.0/16", 8, i)]tolist([ "10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24",])
> cidrhost("10.0.1.0/24", 5)"10.0.1.5"
> cidrnetmask("10.0.0.0/16")"255.255.0.0"Testing Variables and Locals
With configuration loaded, inspect variable values and local computations:
# In your config: variable "environment" { default = "staging" }> var.environment"staging"
# Local computed values> local.name_prefix"staging-myapp"
> local.common_tagstomap({ "Environment" = "staging" "ManagedBy" = "terraform" "Team" = "platform"})Querying State
The console can access resources already in state:
# Read a provisioned resource's attributes> aws_vpc.main.id"vpc-0abc123def456789"
> aws_vpc.main.cidr_block"10.0.0.0/16"
# Reference a count-based resource by index> aws_instance.app[0].private_ip"10.0.1.45"
# Reference a for_each resource by key> aws_subnet.public["a"].id"subnet-0abc123"Testing For Expressions and Conditionals
# For expressions with conditions> [for n in range(10) : n if n % 2 == 0]tolist([ 0, 2, 4, 6, 8,])
# Map transformation> {for k, v in {"a" = 1, "b" = 2, "c" = 3} : k => v * 10}tomap({ "a" = 10 "b" = 20 "c" = 30})
# Conditional expression> var.environment == "production" ? "t3.large" : "t3.micro""t3.micro" # (when environment is "staging")Encoding and Cryptographic Functions
> base64encode("Hello, Terraform!")"SGVsbG8sIFRlcnJhZm9ybSE="
> base64decode("SGVsbG8sIFRlcnJhZm9ybSE=")"Hello, Terraform!"
> jsonencode({"key" = "value", "count" = 3})"{\"count\":3,\"key\":\"value\"}"
> jsondecode("{\"name\":\"terraform\",\"version\":\"1.8\"}")tomap({ "name" = "terraform" "version" = "1.8"})
# File hash — useful for triggering resource updates on file changes> filesha256("scripts/init.sh")"abc123def456..."Practical Debugging Session
# You want to compute names for 3 availability zones> [for i, az in ["us-east-1a", "us-east-1b", "us-east-1c"] : "subnet-public-${i+1}-${az}"]tolist([ "subnet-public-1-us-east-1a", "subnet-public-2-us-east-1b", "subnet-public-3-us-east-1c",])
# Verify your tag merge logic> merge({"Environment" = "prod"}, {"Team" = "platform"}, {"CostCenter" = "eng-42"})tomap({ "CostCenter" = "eng-42" "Environment" = "prod" "Team" = "platform"})
# Test regex before using it in a resource> can(regex("^[a-z][a-z0-9-]{2,62}[a-z0-9]$", "my-bucket-name"))true> can(regex("^[a-z][a-z0-9-]{2,62}[a-z0-9]$", "MY-BUCKET"))falseThe console saves significant time — test expressions interactively here instead of making code changes, running plan, and checking for errors repeatedly.