HCL Basics: Learn Terraform Syntax Step by Step
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:
resourcedefines a Terraform resource block.local_fileis the resource type.petis the logical name assigned to the resource.filenameandcontentare 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_instancefor Amazon EC2 instancesaws_s3_bucketfor Amazon S3 bucketsgoogle_compute_instancefor Google Cloud virtual machinesazurerm_linux_virtual_machinefor 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_instancefor EC2 virtual machinesaws_s3_bucketfor Amazon S3 bucketsaws_dynamodb_tablefor DynamoDB tablesgoogle_compute_instancefor Google Cloud virtual machinesazurerm_resource_groupfor 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 planin 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.
Navigating Provider Documentation
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:
8 free, 100% client-side tools for developers — no signup, no data uploads.
Explore all tools