CHAPTER 03
Terraform Configuration Language (HCL)
Updated: May 15, 2026
25 min read
# CHAPTER 3
Terraform Configuration Language (HCL)
1. Introduction
To command Terraform, you must speak its language. HashiCorp Configuration Language (HCL) is designed to be highly readable by humans while remaining strictly structured for machine parsing. It is neither a full programming language like Python, nor a simple data format like JSON; it is a specialized declarative language built specifically for describing infrastructure. In this chapter, we will dissect the anatomy of HCL, mastering the syntax of blocks, arguments, and identifiers to write our first piece of infrastructure code.2. Learning Objectives
By the end of this chapter, you will be able to:- Understand the core syntax rules of HCL (HashiCorp Configuration Language).
- Define the structure of a Terraform "Block".
- Differentiate between Block Types, Labels, and Arguments.
- Identify proper string, number, and boolean data types in HCL.
- Write a basic HCL configuration without syntax errors.
3. Beginner-Friendly Explanation
Imagine filling out a highly structured form to order a custom car.- The Block Type: "Vehicle" (Tells the factory we are building a car, not a boat).
- The Label: "MyDailyDriver" (A personal nickname so you can refer to it later).
- The Arguments:
- Color = "Red"
- Doors = 4
- Electric = true
In HCL, that exact form looks like this:
hcl
You are simply filling out standardized forms telling the cloud exactly what you want.
4. Anatomy of a Terraform Block
Everything in Terraform is defined inside a Block. A block is the fundamental container for configuration.Here is a real AWS server block:
hcl
Let's break it down:
-
1.
Block Type (
resource): The first word. It tells Terraform what *kind* of block this is. Aresourceblock creates infrastructure. Avariableblock takes input. Anoutputblock prints data.
-
2.
Resource Type (
"awsinstance"): The first label. This is strictly defined by the Provider (AWS). You cannot make this up. It specifically means "AWS EC2 Virtual Machine."
-
3.
Resource Name (
"webserver"): The second label. This is your personal identifier. You can name it"database","frontend", or"steve". This name is only used *inside* your Terraform code to reference the block.
-
4.
Arguments (
ami = ...): The key-value pairs inside the curly braces{ }. These are the settings for the resource.
5. HCL Data Types
When assigning values to arguments, HCL supports standard data types:-
Strings: Must be enclosed in double quotes.
"t2.micro"
-
Numbers: No quotes.
port = 80
-
Booleans:
trueorfalse(No quotes).encrypted = true
-
Lists (Arrays): Enclosed in brackets.
security_groups = ["sg-123", "sg-456"]
- Maps (Dictionaries): Enclosed in curly braces with colons or equals signs.
hcl
6. Mini Project: Create First Terraform Configuration
Let's use HCL to create something real, but harmless. We will use thelocal provider to create a simple text file on your laptop.
Step-by-Step Walkthrough:
-
1.
In your project directory, open
main.tf.
- 2. Paste the following HCL code:
hcl
-
3.
Open your terminal and run
terraform init(to download the local plugin).
-
4.
Run
terraform apply. Typeyeswhen prompted.
-
5.
Observation: Look at your directory! A new file named
helloworld.txthas magically appeared, containing your message. You just provisioned infrastructure!
7. Real-World Scenarios
A developer was trying to create an AWS server with a massive hard drive. They wrotevolumesize = "100". When they ran terraform plan, Terraform threw an error: "Inappropriate value for attribute volumesize: number required." Because they put quotes around "100", HCL treated it as a string of text, not a mathematical number. The AWS API rejected it. Removing the quotes fixed the issue instantly. Understanding basic HCL data types is crucial for passing the strict validations of Cloud APIs.
8. Best Practices
-
Formatting Command: You do not need to spend hours meticulously lining up all your equals signs
=. HashiCorp provides a built-in command. Simply runterraform fmtin your terminal, and Terraform will automatically rewrite your files perfectly aligned according to HCL canonical standards. Run this before committing any code to Git!
9. Security Recommendations
-
Comments: HCL supports comments using
#or//. Use comments aggressively to explain *why* a specific architecture decision was made (e.g.,# Opening port 22 temporarily for audit, REMOVE BY FRIDAY). This provides context for security reviewers auditing the codebase.
10. Troubleshooting Tips
-
Missing Curly Braces: The most common beginner syntax error in HCL is forgetting a closing curly brace
}at the end of a block, especially when nesting Maps (liketags = { ... }) inside the main block. Use VS Code's bracket matching to ensure every{has a corresponding}.
11. Exercises
-
1.
Identify the Block Type, Resource Type, and Resource Name in this line:
resource "aws
-
2.
Run
terraform fmton a messy HCL file and observe how it standardizes the indentation.
12. FAQs
Q: Can I use JSON instead of HCL? A: Technically, yes. Terraform can read.tf.json files. However, this is almost exclusively used when a machine (like a custom script) is auto-generating Terraform code. Humans should always write in HCL, as it supports comments and is infinitely easier to read.
13. Interview Questions
- Q: Break down the anatomical structure of a Terraform HCL configuration block. Explain the difference between the Resource Type and the Resource Name.
-
Q: What is the purpose of the
terraform fmtcommand, and why should it be integrated into a team's CI/CD or pre-commit workflow?
14. Summary
In Chapter 3, we learned the grammar of Infrastructure as Code. We dissected the HashiCorp Configuration Language (HCL), identifying how Blocks act as containers for our declarations. We mastered the taxonomy ofresource blocks, distinguishing between the cloud-defined Resource Type and our internal Resource Name. By writing a functional HCL script to provision a local file, we proved that Terraform code is simply a highly structured blueprint composed of strings, numbers, and maps, waiting to be executed by the core engine.