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 live
  • variables.tf — Where you declare input variables
  • outputs.tf — Where you declare output values
  • provider.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.

TypeExampleUsed For
String"t2.micro"Text values like names and IDs
Number3Counts, sizes, ports
Booleantrue or falseFeature 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, and output.
  • The random provider is a great way to practice writing Terraform without any cloud credentials.

Leave a Comment