Terraform main.tf and File Layout

What main.tf typically contains and how Terraform loads all .tf files in a directory.

What main.tf usually contains

By convention, main.tf holds the core resource definitions and module calls for a configuration. Most teams also use separate files for variables (variables.tf) and outputs (outputs.tf), but Terraform does not enforce this separation.

The provider block can also live in main.tf, especially for small configurations.

What Terraform actually reads

Terraform loads every file that ends in .tf inside the current working directory. It merges them into a single internal configuration graph before doing anything else. That means you can split a large configuration across any number of files and Terraform will treat it as one coherent unit.

Good file names help the team, not the tool. Name files to communicate intent: versions.tf for version constraints, locals.tf for local values.
# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.region
}

resource "aws_s3_bucket" "example" {
  bucket = var.bucket_name
}

A simple convention

Start with a single main.tf and pull blocks into separate files only when the file becomes hard to scan. A 30-line main.tf is easier to navigate than six tiny files.

As the project grows, separating variables, outputs, and data sources keeps each file focused on one concern.