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: NO becomes false)
  • 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.

Terraform native JSON: Terraform's native JSON format uses .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.