What Is HCL in Terraform?
HCL (HashiCorp Configuration Language) is the configuration language used by Terraform, Packer, Vault, Consul, and other HashiCorp tools. It's designed to be human-readable and machine-processable — easier to write than JSON for configuration, more structured than YAML for complex resource definitions.
What HCL looks like
An HCL Terraform configuration defining an AWS S3 bucket:
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-app-assets-prod"
tags = {
Environment = "production"
Project = "my-app"
}
}
variable "region" {
type = string
default = "eu-central-1"
description = "AWS region for the deployment"
}
HCL uses assignment syntax (=), block syntax (curly braces for nested configuration), and string interpolation (${variable}). Comments use # or //.
Why Terraform uses HCL instead of JSON or YAML
Terraform originally accepted JSON as configuration, and still does — any HCL configuration has an equivalent JSON representation. But HCL became the standard because:
- JSON has no comment syntax — documenting configuration decisions inline is impossible
- JSON requires quoting all keys and is more verbose for nested structures
- YAML's implicit type coercion creates subtle bugs (the Norway problem:
enabled: NObecomesfalse) - HCL supports Terraform-specific features like functions, expressions, and dynamic blocks that would be awkward in YAML
HCL vs JSON for Terraform
The same resource in both formats:
# HCL (what you write)
resource "aws_instance" "web" {
ami = "ami-0c02fb55956c7d316"
instance_type = "t3.micro"
}
# JSON (also valid, but more verbose)
{
"resource": {
"aws_instance": {
"web": {
"ami": "ami-0c02fb55956c7d316",
"instance_type": "t3.micro"
}
}
}
}
JSON is useful when Terraform configuration is generated programmatically — code that produces JSON is simpler to write than code that produces HCL. Some infrastructure-as-code tools (CDK for Terraform, Pulumi) generate JSON configurations under the hood.
When to convert between HCL and JSON
Convert HCL to JSON for: programmatic inspection, integration with tools that can read JSON but not HCL, or code generation workflows. Convert JSON to HCL for: making machine-generated configuration human-readable, migrating from a tool that outputs JSON to a HCL-based workflow.
.tf.json extensions. Files with .tf extension are HCL; files with .tf.json are JSON. Both can coexist in the same directory and Terraform handles them transparently.