Terraform Language & Terms
Configurations and the HashiCorp language
A configuration is a complete document in the Terraform language that tells
Terraform how to manage a collection of infrastructure. You author it in the
Author phase of the workflow as one or
more files with a .tf extension.
Directory structure
A configuration lives in a directory that can hold multiple files and subdirectories. It consists of a root module plus an optional tree of child modules. You can put every resource in a single root file, but the best practice is to split files logically.
main.tf- the root module (root configuration); the entry point.- child modules - zero or more, factored into their own subdirectories.
variables.tf- input variables (optional but recommended).outputs.tf- values surfaced after apply (optional but recommended).terraform.tfvars- values assigned to those variables (optional but recommended).
The root module is the directory you run terraform commands in. Terraform
picks up every .tf file in that directory (not just main.tf) and uses
them together to build the plan and the infrastructure. Child modules are
optional - a valid configuration can be a single root module.
HashiCorp Configuration Language (HCL)
Configurations are written in HCL - a JSON-based variant that is both human- and machine-friendly. HCL creates and manages API-based resources (virtual machines, storage buckets, containers, networks), defines the dependencies between them, and declares the data to fetch.
Despite the resemblance, HCL has no traditional statements or control loops.
It exposes a limited set of primitives - variables, resources, outputs,
modules - and expresses logic only through assignments, count, and
interpolation functions. Its simplicity is the point: it keeps Terraform
approachable.
Syntax anatomy
Generic block, then a concrete google_compute_network resource:
| Construct | What it is |
|---|---|
| Block | Lines belonging to a type (resource, variable, output); can be simple or nested inside another block |
| Argument | Assigns a value to a name inside a block; some are mandatory, others optional |
| Identifier | The name of an argument, block type, or construct. Letters, underscores, hyphens, digits - cannot start with a digit |
| Expression | The value assigned to an identifier; simple or complex |
| Comment | Starts with # for a single line |
HCL is declarative - you define the end state of the infrastructure, not the steps to reach it. As a result, the order of blocks or files is irrelevant; Terraform works out the dependency order itself.
Author-phase terms and concepts
While authoring a configuration, you work
with a small vocabulary of building blocks: resources, providers,
variables, outputs, state, and modules. Each maps to a .tf
file or block you write by hand.
Resources
A resource is a code block that defines an infrastructure component - the keyword
resource, a resource type, and a name you choose. Resources are the core building
block, with their own page covering meta-arguments
(count, for_each) and dependencies between resources.
Providers
Providers implement every resource type - without a provider, Terraform can
manage no infrastructure. They expose a service's APIs as Terraform resources
and manage the interactions. You declare them in the terraform block (by
convention in providers.tf), and Terraform downloads the provider plugin
into the root configuration on init.
The source is the global source address on the Terraform Registry
(hashicorp/google); google is the provider's local name, which must also
appear in required_providers. Arguments like project and region are
specific to the Google provider. Provider configuration belongs in the root
module.
The version argument is optional but recommended: it constrains the
provider to a specific version or range so a new release with breaking
changes cannot slip in. If you omit it, Terraform downloads the most recent
provider during init. Likewise, if you include no provider block at all,
Terraform assumes an empty default configuration.
Variables
Input variables parameterize your configuration - they let you customize and share it
without altering the source code, supplying values at run time via CLI options,
environment variables, or a .tfvars file. See their own
page for types, defaults, precedence, and best
practices.
Outputs
Output values expose information from the resources Terraform manages - a bucket URL, an instance IP - so it can be surfaced after apply or consumed by other configurations. See their own page.
State
Terraform records the state of the resources it manages in a state file
(terraform.tfstate). By default it is stored locally, but it can also be
stored remotely - the preferred method when working in a team.
The state file is created and updated automatically - do not modify or edit it. State is covered in detail on its own page.
Modules
A module is a set of Terraform configuration files in a single
directory - even one directory with a single .tf file counts as a module.
Modules are the primary method for code reuse in Terraform: you reuse one by
specifying its source, which can be local (a directory in your config)
or remote (an upstream module from the HashiCorp module registry, or your
own). Modules have their own page.