terraform console & output
terraform console and terraform output are the two commands you reach for when you want to inspect rather than change infrastructure. The console is an interactive REPL where you can evaluate any HCL expression — functions, references to resources, data sources, variables, and local values — against the current state and configuration. terraform output reads the values your root module exposes through output blocks, with flags that make those values trivial to pipe into shell scripts and CI pipelines. Both are read-only, fast, and indispensable for debugging. OpenTofu provides the identical tofu console and tofu output commands.
terraform console
Running terraform console drops you into an interactive prompt where each line you type is evaluated and the result printed immediately. It loads the configuration and the latest state, so references like aws_instance.web.public_ip resolve to real values when the resources exist. It is the fastest way to answer “what does this expression actually produce?” without running a full plan.
terraform console
Output:
> 1 + 2
3
> upper("devcraftly")
"DEVCRAFTLY"
> length(["a", "b", "c"])
3
The console understands the entire HCL function library. This makes it perfect for prototyping a for expression or a string transformation before committing it to a config:
> [for s in ["web", "db", "cache"] : upper(s)]
Output:
[
"WEB",
"DB",
"CACHE",
]
Inspecting state and resources
Because the console binds against state, you can drill into attributes of resources that already exist. Given a simple instance and its data source:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "web-server"
}
}
variable "region" {
type = string
default = "us-east-1"
}
After terraform apply, the console resolves the resource’s computed attributes and your variables:
> aws_instance.web.public_ip
> var.region
> aws_instance.web.tags["Name"]
Output:
"54.210.167.34"
"us-east-1"
"web-server"
Type exit, quit, or press Ctrl+D to leave the session.
The console reads state but never writes it. Evaluating an expression cannot modify resources, so it is completely safe to run against production. If an attribute is only known after apply, the console returns
(known after apply)rather than a concrete value.
Non-interactive console
You can pipe an expression into the console via stdin, which is handy for one-off scripting without entering interactive mode:
echo 'cidrhost("10.0.0.0/16", 5)' | terraform console
Output:
"10.0.0.5"
terraform output
Outputs are the public interface of a module: values declared in output blocks that you want to surface after an apply — an instance IP, a database endpoint, a generated ARN. terraform output reads those values straight from state without re-evaluating the whole configuration.
output "instance_ip" {
description = "Public IP of the web server"
value = aws_instance.web.public_ip
}
output "instance_id" {
value = aws_instance.web.id
}
output "db_password" {
value = random_password.db.result
sensitive = true
}
Running the command with no arguments prints all root-module outputs in HCL-like form:
terraform output
Output:
db_password = <sensitive>
instance_id = "i-0abcd1234ef567890"
instance_ip = "54.210.167.34"
Note that values marked sensitive = true are redacted as <sensitive> to keep secrets out of logs. Pass a single output name to print just that value:
terraform output instance_ip
Output:
"54.210.167.34"
Scripting with -raw and -json
By default terraform output <name> wraps strings in quotes, which is awkward in shell substitution. The -raw flag prints the unquoted, unescaped value of a single string output — exactly what you want to capture into a variable:
ip=$(terraform output -raw instance_ip)
ssh ec2-user@"$ip"
The -json flag emits a machine-readable object containing every output, its type, and a sensitive boolean. Sensitive values are included in JSON (unlike the human format), so handle the output carefully. Combine it with jq to extract structured data:
terraform output -json
Output:
{
"instance_ip": {
"sensitive": false,
"type": "string",
"value": "54.210.167.34"
},
"instance_id": {
"sensitive": false,
"type": "string",
"value": "i-0abcd1234ef567890"
},
"db_password": {
"sensitive": true,
"type": "string",
"value": "s3cr3t-generated-pw"
}
}
terraform output -json | jq -r '.instance_id.value'
Output:
i-0abcd1234ef567890
Prefer
-rawfor a single scalar and-jsonfor multiple or structured values. Avoid parsing the default human-readable format in scripts — its layout is not a stable contract.
Output command flags
| Flag | Behavior |
|---|---|
| (none) | Print all outputs in human-readable HCL form |
<name> | Print just the named output |
-raw | Print the raw string value of a single output, unquoted |
-json | Print all outputs as a JSON object with types and sensitivity |
-state=PATH | Read outputs from a specific local state file (legacy) |
-no-color | Strip ANSI color codes from output |
console vs output
The two commands overlap but serve distinct roles. The console evaluates arbitrary expressions interactively; output reads pre-declared values for automation.
| Aspect | terraform console | terraform output |
|---|---|---|
| Purpose | Evaluate any expression | Read declared output blocks |
| Mode | Interactive REPL (or stdin) | Single command |
| Scripting flag | Pipe via stdin | -raw, -json |
| Reads state | Yes | Yes |
| Modifies anything | Never | Never |
Best Practices
- Use
terraform consoleto prototypeforexpressions, functions, and references before adding them to your config. - Reach for
-rawwhen capturing a single string output into a shell variable; it avoids quote-stripping hacks. - Use
-jsonwithjqfor structured or multiple outputs, and treat the default text format as display-only. - Mark secrets with
sensitive = trueso they are redacted in plan, apply, andterraform outputtext mode. - Remember
-jsonstill exposes sensitive values — never log it unredacted in CI. - Keep the console safe for production use; it is read-only and cannot alter resources or state.
- Pipe expressions into
terraform consolevia stdin for repeatable, non-interactive checks in scripts.