Skip to content
Commitpedia
Log in Join & edit

Terraform concepts: providers, state, plan and apply, modules, and OpenTofu

Terraform describes infrastructure in code, compares it with what exists, and changes only the difference. Learn providers, resources, state, the plan/apply loop, modules and the OpenTofu fork.

Not checked by a trusted editor yet Last edited Outdated?

Edit history of Terraform concepts: providers, state, plan and apply, modules, and OpenTofu: 1 recorded edit
Edit history · 1 edit
Type
Article
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Reading
3 min

Terraform is an infrastructure as code tool. Instead of clicking through a cloud console, you write configuration files that describe the resources you want: servers, networks, DNS records, buckets. Terraform works out what needs to be created, changed or deleted to make reality match the files, shows you that plan, and carries it out when you approve.

Ansible and Terraform overlap but have different strengths. Terraform is best at creating and wiring up infrastructure through APIs; Ansible is best at configuring what runs inside servers. Many teams use Terraform to create machines and Ansible to set them up.

Configuration and resources

Configuration is written in HCL (HashiCorp Configuration Language) in files ending in .tf. Every .tf file in a folder belongs to the same configuration. The central building block is a resource: one object to manage, with a type and a local name.

resource "local_file" "motd" {
  filename = "${path.module}/motd.txt"
  content  = "Welcome!\n"
}

Here local_file is the resource type and motd is the name you use to refer to it elsewhere, as local_file.motd. Input variables (variable blocks) make a configuration reusable, and outputs (output blocks) print values after a run.

Providers

Terraform itself does not know any cloud. Providers are plugins that translate resources into API calls for one platform: AWS, Azure, Google Cloud, Kubernetes, vSphere, DNS services, and many more. You declare which providers you need, and terraform init downloads them from the registry.

terraform {
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "~> 2.5"
    }
  }
}

~> 2.5 allows newer 2.x releases but not 3.0. init records the exact versions and checksums it chose in the dependency lock file .terraform.lock.hcl; commit that file so everyone gets the same provider versions.

State

Terraform keeps a state file that maps each resource in your code to the real object it created, for example “aws_instance.web is instance i-0abc…”. Without state Terraform could not tell which objects it owns. By default state is a local file called terraform.tfstate.

State can contain secrets such as generated passwords, in plain text. Do not commit it to Git. For team work, store it in a remote backend with locking, so two people cannot apply at the same time.

The workflow: write, plan, apply

terraform init       # download providers and modules, set up the backend
terraform fmt        # format the files
terraform validate   # check syntax and references
terraform plan       # show what would change
terraform apply      # show the plan again and apply it after you type yes

The plan marks each resource with a symbol: + create, ~ update in place, - destroy, and -/+ destroy and re-create (replace). Read every plan before applying. A replace on a database or a disk means data loss unless you planned for it.

Because Terraform compares desired and actual state, running apply again with no code changes reports that no changes are needed. That is the same idea as idempotency in Ansible.

Modules

The folder you run Terraform in is the root module. A module block calls a child module: another folder (or a registry or Git source) with its own variables, resources and outputs. Modules let you package a pattern, such as “a VM with a disk and a DNS record”, once and reuse it with different inputs.

module "web" {
  source = "./modules/vm"

  name = "web1"
  size = "small"
}

Public modules are published on the Terraform Registry. When you use a registry module, also set a version so updates are deliberate.

OpenTofu

OpenTofu is an open-source fork of Terraform, created after HashiCorp moved Terraform from an open-source license to the Business Source License (BUSL). OpenTofu is licensed under MPL-2.0 and is a Linux Foundation project. Its command is tofu instead of terraform (tofu init, tofu plan, tofu apply), it reads the same .tf files and uses the same providers.

OpenTofu aims to stay compatible with Terraform configurations, and the projects have since added different features. One OpenTofu addition is built-in encryption of state and plan files. If you switch an existing project, back up the state first and follow the official migration guide for your Terraform version.

Official documentation

See also

Repos in the wild

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Commitpedia +4,526 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?