Documentation Index Fetch the complete documentation index at: https://mintlify.com/hashicorp/terraform/llms.txt
Use this file to discover all available pages before exploring further.
Terraform Configuration Syntax
Terraform configurations are written in HCL (HashiCorp Configuration Language), which is designed to be both human-readable and machine-parseable. This page covers the detailed syntax rules.
File Extensions
Terraform supports two file formats:
.tf - Native HCL syntax (recommended)
.tf.json - JSON syntax for machine generation
This documentation focuses on the native HCL syntax, which is the standard format for human-authored configurations.
Basic Syntax
Blocks
Blocks are the primary structural element. A block has a type, optional labels, and a body:
< BLOCK_TYPE > "<LABEL>" "<LABEL>" {
# Block body
< ARGUMENT > = < EXPRESSION >
< NESTED_BLOCK > {
# Nested block body
}
}
Example
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
network_interface {
device_index = 0
description = "Main network interface"
}
}
In this example:
resource is the block type
"aws_instance" and "web" are labels
ami and instance_type are arguments
network_interface is a nested block
Arguments
Arguments assign values within blocks:
< IDENTIFIER > = < EXPRESSION >
The identifier must be a valid variable name (letters, digits, underscores, and hyphens).
Identifiers
Valid identifiers:
Start with a letter or underscore
Contain letters, digits, underscores, and hyphens
Are case-sensitive
variable "instance_type" { } # Valid
variable "instance-type" { } # Valid
variable "_private" { } # Valid
variable "2nd_instance" { } # Invalid - starts with digit
While hyphens are allowed in identifiers, underscores are preferred for consistency with most programming languages.
Expressions
Expressions produce values and can be:
Literal Values
# String
name = "example"
# Number
count = 3
pi = 3.14159
# Boolean
enabled = true
disabled = false
# Null
default_value = null
Collections
# List/tuple
az_list = [ "us-west-2a" , "us-west-2b" , "us-west-2c" ]
# Map/object
tags = {
Name = "example"
Environment = "production"
}
References
Reference other values in the configuration:
# Resource attribute
ami = aws_ami . ubuntu . id
# Variable
instance_type = var . instance_type
# Local value
subnet_id = local . primary_subnet
# Data source
vpc_id = data . aws_vpc . main . id
Operators
Terraform supports standard operators:
# Arithmetic
result = 2 + 3 # 5
result = 10 - 4 # 6
result = 3 * 4 # 12
result = 10 / 2 # 5
result = 10 % 3 # 1
# Comparison
equal = 5 == 5 # true
not_equal = 5 != 3 # true
greater = 5 > 3 # true
greater_or_equal = 5 >= 5 # true
# Logical
and_op = true && false # false
or_op = true || false # true
not_op = ! false # true
Conditional Expressions
instance_type = var . environment == "production" ? "t2.large" : "t2.micro"
For Expressions
Transform collections:
# List transformation
uppercase_names = [ for name in var . names : upper (name)]
# Map transformation
port_map = { for k , v in var . ports : k => v + 1000 }
# Filtering
production_instances = [ for i in var . instances : i if i . environment == "production" ]
Splat Expressions
Shorthand for extracting attributes:
# Extract all IDs
instance_ids = aws_instance . web [ * ] . id
# Works with resources created with count
private_ips = aws_instance . web [ * ] . private_ip
String Templates
Interpolation
Embed expressions in strings:
greeting = "Hello, ${ var . name } !"
path = "/var/lib/ ${ var . service } /data"
Directives
Control whitespace and flow:
# For loop
user_names = << EOT
%{ for name in var . users ~ }
- ${ name }
%{ endfor ~ }
EOT
# Conditional
config = << EOT
%{ if var . debug_mode ~ }
debug = true
%{ else ~ }
debug = false
%{ endif ~ }
EOT
Heredoc Syntax
Multi-line strings:
user_data = <<- EOT
#!/bin/bash
echo "Hello World"
apt-get update
apt-get install -y nginx
EOT
Three comment styles:
# Single-line comment (preferred)
// Alternative single-line comment
/*
Multi-line comment
Useful for larger blocks
*/
Special Characters
Escaping
Escape special characters in strings:
message = "Quote: \" Hello \" and newline: \n "
path = "C: \\ Users \\ Admin"
template = "$${not_interpolated}"
Unicode
Unicode characters are supported:
variable "π" {
default = 3.14159265359
}
output "emoji" {
value = "🚀"
}
Style Conventions
Use 2 spaces for indentation (not tabs): resource "aws_instance" "example" {
ami = "ami-12345678"
network_interface {
device_index = 0
}
}
Align values for better readability: resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
subnet_id = var . subnet_id
}
Use blank lines to separate logical sections: variable "region" {
type = string
}
variable "instance_type" {
type = string
}
Terraform includes a formatter:
# Format current directory
terraform fmt
# Format specific file
terraform fmt main.tf
# Check if files are formatted
terraform fmt -check
JSON Syntax
For machine-generated configurations:
{
"resource" : {
"aws_instance" : {
"web" : {
"ami" : "ami-12345678" ,
"instance_type" : "t2.micro"
}
}
}
}
The JSON syntax is functionally equivalent to HCL but is less human-friendly. Use it only when generating configurations programmatically.
Validation
The parser validates syntax according to the HCL specification. Common errors include:
Missing closing braces
Invalid identifier names
Incorrect expression syntax
Mismatched quotes
Use terraform validate to check for syntax errors:
Next Steps
Expressions Learn about expression syntax in detail
Functions Explore built-in functions