Skip to content

HCL Syntax: Terraform Configuration Language Guide

DodaTech 4 min read

In this tutorial, you'll learn about HCL Syntax: Terraform Configuration Language Guide. We cover key concepts, practical examples, and best practices.

HashiCorp Configuration Language (HCL) is the syntax used by Terraform to define infrastructure resources, providers, variables, and outputs in a human-readable, machine-parseable format.

What You'll Learn

In this tutorial, you will learn HCL syntax fundamentals -- blocks, arguments, identifiers, data types, expressions, and string templates -- to write Terraform configuration files with confidence.

Why It Matters

Every Terraform configuration is written in HCL. Understanding the syntax deeply lets you write expressive, maintainable infrastructure code. Misplaced braces, incorrect data types, or malformed expressions cause plan and apply failures.

Real-World Use

Durga Antivirus Pro's entire infrastructure library uses HCL modules with consistent syntax patterns. Developers write reusable HCL blocks for auto-scaling groups, load balancers, and database clusters that hundreds of team members consume.

HCL Structure

Blocks and Arguments

An HCL file consists of blocks (containers delimited by braces) and arguments (key-value pairs inside blocks).

# A resource block with two arguments
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}

Expected output: Terraform parses this as a resource block of type aws_instance named web with two arguments.

Identifiers

Block labels and argument names are identifiers. They must start with a letter or underscore and contain only letters, digits, underscores, and hyphens.

# Valid identifiers
resource "aws_s3_bucket" "my_bucket" {
  bucket = "my-company-logs"
  tags = {
    Environment = "Production"
  }
}

Data Types

HCL supports primitive types (string, number, bool) and complex types (list, map, set, object, tuple).

# Data type examples
variable "region" {
  type    = string
  default = "us-east-1"
}

variable "instance_types" {
  type    = list(string)
  default = ["t2.micro", "t3.small", "t3.medium"]
}

variable "tags" {
  type = map(string)
  default = {
    Environment = "Production"
    ManagedBy   = "Terraform"
  }
}

Expected output: Each variable enforces its declared type. Passing a number to a string variable causes a type error during planning.

Expressions and Interpolation

String Templates

locals {
  name_prefix = "dodatech"
  environment = "prod"
  full_name   = "${local.name_prefix}-${local.environment}-server"
}

output "instance_name" {
  value = local.full_name
}

Expected output:

instance_name = "dodatech-prod-server"

Conditional Expressions

variable "env" {
  type    = string
  default = "dev"
}

locals {
  instance_type = var.env == "prod" ? "t3.large" : "t3.micro"
}

output "selected_type" {
  value = local.instance_type
}

Expected output: For env set to "dev", the output is t3.micro. For "prod", it is t3.large.

Heredoc Strings

For multi-line strings like user data scripts, use heredoc syntax:

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  user_data = <<-EOF
    #!/bin/bash
    echo "Hello from Terraform" > /tmp/hello.txt
    apt-get update
    apt-get install -y nginx
    systemctl start nginx
  EOF
}

Expected output: The user_data argument receives the entire multi-line script with leading tabs stripped.

Comments

HCL supports three comment styles:

# Single-line comment: use this for short explanations

// Also a single-line comment: less common in HCL

/*
  Multi-line comment: use for longer descriptions
  that span several lines of explanatory text
*/

Common Mistakes

1. Missing or Extra Braces

Every opening brace needs a closing brace. Count your braces when you see "unexpected end of file" errors.

2. Using Double Quotes Inside Descriptions

Apostrophes inside single-quoted YAML descriptions break parsing. Use single quotes or escape them.

3. Confusing Assignment and Equality

In HCL, = is assignment. Equality comparison uses ==. Writing if var.env = "prod" causes a parse error.

4. Incorrect Type Declaration

Declaring type = string and passing a list causes a type mismatch error at plan time.

5. Mixing Block Types

Using the wrong block type structure -- for example, putting a resource argument inside a provider block -- causes validation errors.

Practice Questions

1. What are the three comment styles available in HCL? # for single-line, // for single-line, and /* */ for multi-line comments.

2. How do you write a conditional expression in Terraform? Use the ternary syntax: condition ? true_value : false_value, for example var.env == "prod" ? "t3.large" : "t3.micro".

3. What is the difference between a block and an argument? A block is a container delimited by braces that may contain other blocks and arguments. An argument assigns a value to a name using =.

4. How do you create multi-line strings in HCL? Use the heredoc syntax <<-EOF with EOF terminator. The <<- variant strips leading tabs.

5. Challenge: Write an HCL configuration with three variables (string, list, map), a local value that combines them, and an output that prints the result.

Mini Project: HCL Playground

Create a file called syntax-playground.tf that defines a provider, one resource, two variables, a local value, and three outputs. Run <a href="/devops/terraform/">terraform</a> validate and <a href="/devops/terraform/">terraform</a> fmt to verify correctness and formatting.

Install Terraform
Terraform Providers

What's Next

Master HCL syntax, then configure Providers to connect to AWS, Azure, or GCP and begin managing real infrastructure.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro