HCL Basics: Learn Terraform Syntax Step by Step

Published: 2025-07-25
7 min read
Share:

HCL Basics form the foundation of writing infrastructure as code with Terraform. If Terraform configuration files look unfamiliar right now, don't worry. Once you understand how HashiCorp Configuration Language (HCL) is structured, writing Terraform configurations becomes much easier.

Terraform uses HCL to define infrastructure resources, variables, outputs, providers, and modules. Whether you're a DevOps Engineer, SRE, Platform Engineer, or software developer learning infrastructure automation, understanding HCL is the first step.

If you're completely new to Terraform, start with our guide on getting started with Terraform before moving on to more advanced concepts.

What Is HashiCorp Configuration Language (HCL)?

HashiCorp Configuration Language (HCL) is a human-readable configuration language created by HashiCorp and used by Terraform to describe infrastructure.

Instead of writing imperative instructions that tell Terraform how to create resources, you define the desired state of your infrastructure. Terraform then determines the actions required to reach that state.

HCL is designed to be:

  • Human-readable
  • Easy to learn
  • Version-control friendly
  • Suitable for reusable infrastructure definitions

Terraform configurations are stored in files with the .tf extension and use HCL syntax by default.

By understanding HCL basics, you can create maintainable and reusable infrastructure definitions for cloud and on-premises environments.

HCL Basics: Understanding Blocks and Arguments

HCL files are primarily built from two components:

  • Blocks: Top-level structures surrounded by curly braces {}.
  • Arguments: Key-value pairs inside blocks that configure behavior.

A simple Terraform resource typically contains both.

Example Resource Block

resource "local_file" "pet" {
  filename = "/root/pets.txt"
  content  = "We love pets"
}

In this example:

  • resource defines a Terraform resource block.
  • local_file is the resource type.
  • pet is the logical name assigned to the resource.
  • filename and content are arguments.

One mistake beginners often make is assuming every Terraform resource supports the same arguments. Each resource has its own schema, which is defined by its provider documentation.

How Resource Blocks Work in Terraform

Every Terraform-managed infrastructure component is represented as a resource block.

The resource declaration follows this structure:

resource "<resource_type>" "<resource_name>" {
  argument = value
}

For example:

resource "local_file" "pet" {
  filename = "/root/pets.txt"
  content  = "We love pets"
}

Terraform identifies the resource type and uses the appropriate provider plugin to manage it.

Examples include:

  • aws_instance for Amazon EC2 instances
  • aws_s3_bucket for Amazon S3 buckets
  • google_compute_instance for Google Cloud virtual machines
  • azurerm_linux_virtual_machine for Azure virtual machines

Understanding resource blocks is one of the most important HCL basics because nearly every Terraform configuration contains them.

Pro Tip: In production environments, Terraform projects often contain dozens or hundreds of resource blocks. Consistent naming conventions make troubleshooting, collaboration, and code reviews significantly easier.

Common HCL Data Types

HCL supports several built-in data types.

String

name = "web-server"

Number

instance_count = 3

Boolean

enabled = true

List

availability_zones = [
  "us-east-1a",
  "us-east-1b"
]

Map

tags = {
  Environment = "dev"
  Owner       = "platform-team"
}

Object

server = {
  name = "web-01"
  cpu  = 2
  ram  = 4
}

As you progress, you'll frequently combine these data types with Terraform variables and modules to create reusable infrastructure.

HCL Example: Creating a Local File with Terraform

A simple way to learn HCL is by creating a local file using Terraform.

Step 1: Create a Project Directory

mkdir ~/terraform-local-file
cd ~/terraform-local-file

Step 2: Create a Terraform Configuration File

Create a file named local.tf.

Add the following configuration:

resource "local_file" "pet" {
  filename = "/root/pets.txt"
  content  = "We love pets"
}

Step 3: Initialize Terraform

terraform init

Terraform downloads the required provider plugins and prepares the working directory.

Step 4: Review the Execution Plan

terraform plan

This command shows what Terraform intends to create before making any changes.

Step 5: Apply the Configuration

terraform apply

Terraform will prompt for confirmation before creating the resource.

Step 6: Verify the Result

cat /root/pets.txt

At this point, you should have a real file created by Terraform. For many beginners, this is where the relationship between HCL configuration and infrastructure changes becomes clear.

Exploring Other Resource Types in HCL

The same HCL syntax is used to define resources across many cloud providers.

Examples include:

  • aws_instance for EC2 virtual machines
  • aws_s3_bucket for Amazon S3 buckets
  • aws_dynamodb_table for DynamoDB tables
  • google_compute_instance for Google Cloud virtual machines
  • azurerm_resource_group for Azure resource groups

If you're working with AWS resources, you may find these guides helpful:

Each resource type has different required and optional arguments, which is why consulting provider documentation is a normal part of daily Terraform work.

How Terraform Interprets HCL Files

Terraform follows a predictable workflow when processing HCL configurations.

terraform init

terraform init

This command:

  • Identifies required providers
  • Downloads provider plugins
  • Initializes the working directory

terraform plan

terraform plan

This command compares:

  • Desired state in HCL files
  • Current infrastructure state

Terraform then generates an execution plan.

terraform apply

terraform apply

This command applies approved changes to your infrastructure.

Real-World Workflow: Most engineering teams run terraform plan in CI/CD pipelines before applying changes. This allows infrastructure changes to be reviewed and validated before reaching production environments.

You can learn more about these commands in our guide on Terraform commands explained.

Terraform supports hundreds of providers through the official Terraform ecosystem.

The best place to explore providers and resources is the official Terraform Registry.

The registry provides:

  • Provider documentation
  • Resource references
  • Argument descriptions
  • Usage examples
  • Version information

For example:

  • The Local provider contains only a small number of resources.
  • The AWS provider contains hundreds of resources covering compute, networking, storage, databases, security, and more.

Even experienced Terraform engineers regularly consult provider documentation because every resource type has different arguments and requirements.

You should also review the official Terraform documentation available at HashiCorp Developer.

Where HCL Fits in a Terraform Project

As your Terraform knowledge grows, you'll use HCL for much more than resource definitions.

Common Terraform components written in HCL include:

  • Resources
  • Variables
  • Outputs
  • Modules
  • Providers
  • Backend configurations
  • Meta-arguments

To continue learning, explore:

These concepts build directly on the HCL basics covered in this guide.

Conclusion

Learning HCL basics is the first step toward becoming productive with Terraform.

Once you understand blocks, arguments, resource definitions, and data types, you'll be able to read and write Terraform configurations with confidence. From there, the natural progression is learning Terraform variables, modules, providers, and state management.

The best way to improve is simple: write configurations, run Terraform commands, review the results, and keep building.

FAQ — HCL Basics

What is HCL used for in Terraform?

HCL (HashiCorp Configuration Language) is used to define infrastructure resources, variables, outputs, modules, and provider configurations in Terraform.

Can I use JSON instead of HCL?

Yes. Terraform supports JSON syntax, but HCL is the recommended format because it is easier for humans to read and maintain.

Do all Terraform resources use the same arguments?

No. Every resource type has its own set of required and optional arguments defined by the provider documentation.

Is HCL case-sensitive?

Yes. Resource names, variable names, and identifiers are case-sensitive and should be used consistently.

What are the most common HCL data types?

The most common HCL data types are:

  • String
  • Number
  • Boolean
  • List
  • Map
  • Object

What's the difference between HCL and YAML?

HCL is specifically designed for infrastructure configuration and supports expressions, references, and Terraform-specific features. YAML is a general-purpose data serialization format.

Where can I learn more about HCL syntax?

The best sources are:

Free Engineering ToolsNEW

8 free, 100% client-side tools for developers — no signup, no data uploads.

Explore all tools