What are the different files used by Terraform?
Published on 04 Sep 2025 by Adam Lloyd-Jones
Terraform uses various files to define, manage, and track your infrastructure. These files include configuration files, state files, and other supporting files, each serving a specific purpose in the Terraform workflow.
Here’s a breakdown of the files used by Terraform:
-
Terraform Configuration Files (
.tf
files):- These are text files that specify the infrastructure you want to create, acting as a blueprint for your cloud-based applications.
- They are written in HashiCorp Configuration Language (HCL), a declarative language where you describe the desired state of your infrastructure.
- While you can use any filename ending with
.tf
, common conventions include:main.tf
: Often contains the core resource definitions.variables.tf
: Defines input variables, allowing you to customize a module’s behavior without editing the module itself. These variables can define parameters like application names, locations, or Kubernetes versions.outputs.tf
: Defines output values that can be easily retrieved after applying the configuration. This is how Terraform exposes provisioned data.providers.tf
: Configures the required provider plugins and their versions.
- Terraform automatically executes all
.tf
code files in the current working directory. - Terraform code can also be written in pure JSON in files with the
.tf.json
extension.
-
Terraform Variable Definition Files (
.tfvars
files):- These files are used to specify values for variables defined in your Terraform configuration.
- They allow you to separate variable definitions from their values, which is useful for managing multiple environments (e.g., development, staging, production) or for sharing configuration data.
- Commonly named
terraform.tfvars
or*.auto.tfvars
(e.g.,dev.tfvars
), these files can be in HCL or JSON format. - Terraform automatically loads
terraform.tfvars
,terraform.tfvars.json
, or files ending with.auto.tfvars
or.auto.tfvars.json
. You can also explicitly specify them using the-var-file
option.
-
Terraform State Files (
.tfstate
files):- Terraform records information about what infrastructure it has created in a state file, typically named
terraform.tfstate
. - This file maps the Terraform resources in your configuration to their real-world counterparts (e.g., a resource to an EC2 instance ID).
- It’s crucial for tracking your infrastructure’s current state, ensuring consistency, detecting configuration drift, and applying precise updates.
- State files are in a custom JSON format and should never be manually edited to avoid corruption. Terraform provides commands like
terraform import
orterraform state
to manipulate state safely. - By default, state is stored locally, but for team collaboration and resilience, remote backends (e.g., Azure Storage, AWS S3, Google Cloud Storage, Terraform Cloud) are recommended to store state files.
- Sensitive data, such as passwords, are stored in plain text within the state file, making secure storage essential.
- Terraform records information about what infrastructure it has created in a state file, typically named
-
Terraform Dependency Lock File (
.terraform.lock.hcl
):- This file records the provider selections (versions and cryptographic hashes) made by
terraform init
. - It ensures that Terraform uses the same provider versions by default in future
terraform init
runs, preventing unexpected changes or issues. - It’s important to include this file in your version control repository.
- The package hashes within this file can differ based on the operating system and architecture.
- This file records the provider selections (versions and cryptographic hashes) made by
-
Terraform’s Scratch Directory (
.terraform
directory):- This hidden subdirectory is created by
terraform init
and contains cached provider plugins and other temporary files. - It should generally be ignored in version control (
.gitignore
).
- This hidden subdirectory is created by
-
CLI Configuration File (
terraform.rc
or.terraformrc
):- This file is used to configure Terraform’s command-line interface (CLI) behavior, such as plugin cache directories or credentials for Terraform Cloud/Enterprise.
-
Template Files (
.tpl
extension):- Terraform can use templates to generate dynamic content for files or scripts.
- The
templatefile
function reads a.tpl
file and renders its content using variables. This is useful for creating configuration files (e.g., Ansible inventory files, cloud-init scripts) with dynamic data.
-
Script Files (e.g.,
.sh
,.ps1
):- Terraform can execute local programs or scripts using the
local-exec
provisioner or theexternal
data source. These scripts can perform bootstrapping, configuration management, or data fetching. - Examples include Bash scripts (
.sh
) or PowerShell scripts (.ps1
).
- Terraform can execute local programs or scripts using the
In essence, Terraform relies on a well-defined ecosystem of files to translate your infrastructure desires into actual cloud resources, much like a chef uses a recipe, ingredient lists, and a pantry inventory to prepare a meal. The .tf
files are the recipe, the .tfvars
files are the ingredient lists, and the .tfstate
file is the real-time inventory of what’s cooking.
Terraform leverages a structured approach to defining infrastructure through a set of distinct file types, with main.tf
, variables.tf
, outputs.tf
, and providers.tf
being among the most fundamental configuration files. While Terraform processes all files with a .tf
extension in the working directory, these naming conventions are widely adopted for clarity and organization within a project. Terraform code can also be written in pure JSON in files with the .tf.json
extension.
Here’s a detailed look at the functions of these core files:
-
main.tf
- Primary Purpose: This file typically serves as the main entry point and contains the core resource definitions for your Terraform project. It acts as the blueprint, specifying the infrastructure you want to create.
- Content: A
main.tf
file will often includeterraform
blocks to define global settings,provider
blocks to configure cloud providers,resource
blocks to declare individual infrastructure components, andmodule
blocks to call reusable infrastructure code. - Role in Modules: When building a module,
main.tf
defines the actual infrastructure resources that the module provides. For root modules (the top-level configuration),main.tf
orchestrates calls to other modules and resources. - Flexibility: While it’s a common convention, the structure and filenames are not strictly dictated by Terraform, allowing teams to experiment with what works best for their projects. However, a well-organized
main.tf
or a collection of logically split.tf
files (e.g.,container-registry.tf
,kubernetes-cluster.tf
,resource-group.tf
) enhances readability and maintainability.
-
variables.tf
- Primary Purpose: This file is dedicated to defining input variables for a Terraform configuration or module. These variables act as parameters, allowing users to customize the behavior of a module without altering its source code.
- Arguments for Variables: Each
variable
block can include several optional arguments to enhance flexibility and clarity:description
: A human-readable explanation of the variable’s purpose, aiding documentation.type
: Specifies the expected data type (e.g.,string
,number
,bool
,list
,map
,object
) to ensure robust code and catch errors early.default
: Sets a fallback value if no explicit value is provided. If no default is set and no value is provided, Terraform will prompt the user.sensitive
: Marks the variable as sensitive to prevent its value from being displayed in logs or the CLI output, crucial for security (e.g., passwords, API keys).nullable
: Specifies whether the variable can be assigned anull
value.validation
: A special subblock for adding custom checks on passed-in values, allowing module developers to enforce specific formats or conditions (e.g., usingregex
functions).
- Reusability: Input variables are fundamental for creating reusable, configurable modules, functioning similarly to arguments in programming functions.
-
outputs.tf
- Primary Purpose: This file defines output values that make data generated by Terraform easily accessible and reusable after applying a configuration.
- Exposing Information: Outputs serve several key functions:
- Retrieving Data: They allow you to extract and display information about provisioned resources (e.g.,
registry_hostname
,alb_dns_name
,webapp_url
) in the terminal or for external consumption. - Debugging: Useful for debugging Terraform code and understanding the details of created infrastructure.
- Inter-Module Communication: Child modules can expose specific resource attributes to their parent modules or other configurations, enabling the composition of larger systems from smaller, interconnected modules.
- CI/CD Integration: Output values are often used in Continuous Integration/Continuous Deployment (CI/CD) pipelines to pass information between stages.
- Retrieving Data: They allow you to extract and display information about provisioned resources (e.g.,
- Arguments for Outputs: An
output
block typically includes:value
: The actual data or expression to be exposed.description
: Explains the purpose of the output.sensitive
: Marks the output as sensitive, preventing its value from being displayed in the CLI output or logs, especially important when dealing with credentials. Note that sensitive data is still stored in plain text in the state file, necessitating secure state management.depends_on
: Explicitly declares dependencies on other resources or modules, ensuring proper ordering.
- Analogy: Outputs are like the return values of functions in other programming languages.
-
providers.tf
- Primary Purpose: This file defines and configures the provider plugins that Terraform will use to interact with various cloud platforms or services. Providers are the bridge between Terraform’s generic language and the specific APIs of different vendors.
- Content: A
providers.tf
file usually contains two main types of blocks related to providers:terraform
block withrequired_providers
: This block specifies the source (e.g.,hashicorp/azurerm
) and version constraints for the provider plugins Terraform needs to download. This ensures consistent provider versions across deployments.provider
block: This configures provider-specific settings, such as the AWS region, authentication credentials, or other parameters relevant to how Terraform will connect to that particular service.
- Module Interaction: It’s a best practice for root modules (the top-level configuration) to define and configure providers. Child modules should not define providers directly; instead, they inherit provider configurations from their parent module or specify them through arguments.
- Dependency Lock File: When
terraform init
is run, a.terraform.lock.hcl
file is generated, which records the selected provider versions and their cryptographic hashes. This ensures that futureterraform init
runs use the same provider versions by default, preventing unexpected changes. - Analogy: If
main.tf
is the recipe,providers.tf
is where you list which kitchen appliances (cloud platforms) you’ll use and how to connect them (configure regions, credentials).
These files collectively form the backbone of a Terraform project, enabling you to declaratively define, configure, and manage your infrastructure efficiently and systematically.
Related Posts
- How Infrastructure as Code delivers unprecedented time savings
- ClickOps vs. IaC: Why Terraform wins in the modern cloud era
- What is Terraform?
- The Diverging Paths of Infrastructure as Code: How OpenTofu Handles State Management Differently from Terraform
- Making infrastructure as code (IaC) better: A modular and scalable approach
- What is OpenTofu? Terraform’s open-source alternative
- Deploy Azure like a pro: your first Terraform main.tf made simple
- The function of the main.tf file
- The Essential Guide to Docker for Packaging and Deploying Microservices
- Understanding OpenTofu config files
- Why developers are moving away from Terraform—and what they're choosing instead