Terraform Your First Configuration File
Writing your first Terraform configuration file is simpler than most people expect. This topic teaches you the structure of a Terraform file, the language it uses, and how to write a real (though minimal) configuration from scratch.
What Is HCL
Terraform files use a language called HCL — HashiCorp Configuration Language. HCL is not a programming language. It is a declarative configuration language, which means you describe what you want — not how to create it.
Declarative vs Imperative — A Kitchen Analogy
- Imperative (step-by-step): "Turn on the oven, wait for 180°C, put dough in tray, place tray in oven, bake for 30 minutes, remove tray."
- Declarative (describe the outcome): "I want a baked loaf of bread."
Terraform is declarative. You say "I want a virtual machine with 2 CPUs and 4 GB RAM in the us-east-1 region" and Terraform figures out how to make that happen.
Terraform File Extensions
Terraform reads all files ending in .tf inside your working directory. A project can have one file or many — Terraform merges them all before running. The most common file names you will see across projects are:
main.tf— Where your main resource definitions livevariables.tf— Where you declare input variablesoutputs.tf— Where you declare output valuesprovider.tf— Where you configure the cloud provider
These names are conventions, not rules. Terraform does not care what you name your files as long as they end in .tf.
The Basic Structure of a Terraform Block
Everything in HCL is a block. A block has a type, optional labels, and a body enclosed in curly braces.
block_type "label_one" "label_two" {
argument_name = value
}
Diagram: Anatomy of a Terraform Block
resource "aws_instance" "web_server" {
^ ^ ^
Block Type Resource Type Resource Name
(your chosen name)
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
^ ^
Argument Name Argument Value
}
Your First Terraform File
This example creates a simple random string using the hashicorp/random provider — a safe way to learn without needing a cloud account or any credentials.
Step 1: Create a project folder
mkdir my-first-terraform cd my-first-terraform
Step 2: Create main.tf
terraform {
required_providers {
random = {
source = "hashicorp/random"
version = "~> 3.5"
}
}
}
provider "random" {}
resource "random_pet" "server_name" {
length = 2
separator = "-"
}
output "generated_name" {
value = random_pet.server_name.id
}
What Each Block Does
- terraform block: Declares which providers your configuration needs and what version to use.
- provider block: Configures the provider (in this case, the random provider needs no configuration).
- resource block: Defines a resource you want to create. Here it is a random pet name.
- output block: Prints a value to the terminal after Terraform runs.
HCL Data Types at a Glance
HCL supports several value types. You use them as argument values inside blocks.
| Type | Example | Used For |
|---|---|---|
| String | "t2.micro" | Text values like names and IDs |
| Number | 3 | Counts, sizes, ports |
| Boolean | true or false | Feature flags, toggles |
| List | ["us-east-1", "eu-west-1"] | Multiple values of the same type |
| Map | { name = "app", env = "prod" } | Key-value pairs (like tags) |
Comments in HCL
You can add comments to explain your code. Terraform ignores comments when it runs.
# This is a single-line comment // This also works as a single-line comment /* This is a multi-line comment */
Key Points
- HCL is a declarative language — describe what you want, not how to build it.
- All Terraform files end in
.tf. Terraform reads all of them in a directory together. - A Terraform block has a type, optional labels, and key-value arguments inside curly braces.
- The four main blocks are:
terraform,provider,resource, andoutput. - The random provider is a great way to practice writing Terraform without any cloud credentials.
