HCL Syntax
Terraform files are written in HCL, a readable configuration language built from blocks and arguments.
block_type "label" "name" {
argument = value
}Terraform configuration is written in HCL (HashiCorp Configuration Language). It is designed to be easy for humans to read and write, while still being machine friendly.
Files
Configuration lives in files ending in .tf. Terraform loads every .tf file in the working directory and treats them as one combined configuration, so you can split code across files like main.tf, variables.tf and outputs.tf.
Two building blocks
- Blocks — containers like
resource,variableorprovider. - Arguments —
name = valueassignments inside a block.
Example
# An S3 bucket declared in HCL
resource "aws_s3_bucket" "assets" {
bucket = "soundscode-assets-2026"
tags = {
Environment = "dev"
Team = "web"
}
}When to use it
- An engineer reads an existing Terraform file and instantly understands its structure because HCL's block-and-argument syntax mirrors JSON but is far more readable.
- A team enforces consistent HCL formatting with terraform fmt in a pre-commit hook, keeping all .tf files in canonical style automatically.
- A new Terraform user converts a raw AWS CloudFormation YAML template to HCL, appreciating that HCL drops the excessive quoting and nesting.
More examples
Basic HCL block structure
Shows a resource block with its type, two labels, simple argument assignments, and a nested map argument.
# Block type, labels, and body
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "WebServer"
}
}String interpolation in HCL
Demonstrates embedding a variable reference inside a string using the ${...} interpolation syntax.
variable "env" {
default = "prod"
}
resource "aws_s3_bucket" "data" {
bucket = "myapp-${var.env}-data"
}Multi-line string with heredoc
Uses a heredoc (<<-EOF) to embed a multi-line shell script as the user_data value without escaping newlines.
resource "aws_instance" "app" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
user_data = <<-EOF
#!/bin/bash
apt-get update
apt-get install -y nginx
EOF
}
Discussion