The Terraform Workflow
Terraform’s commands make much more sense when you understand the workflow they form. init, validate, fmt, plan, apply, and destroy are not six unrelated commands. Together they form a cycle in which you prepare a configuration, inspect the proposed changes, apply them, modify the configuration, and eventually remove the infrastructure.
The Terraform Workflow
A useful high-level model is:
flowchart LR
A[Write configuration] --> B[terraform fmt]
B --> C[terraform init]
C --> D[terraform validate]
D --> E[terraform plan]
E --> F[Review plan]
F --> G[terraform apply]
G --> H[Infrastructure]
H --> I[Modify configuration]
I --> B
G --> J[terraform destroy]
The exact sequence can vary in day-to-day work, but the mental model is important:
You change configuration, Terraform evaluates the change, you review what Terraform proposes, and only then do you apply it.
terraform init
Initialization prepares a working directory for Terraform.
Run:
terraform initTerraform examines the configuration and installs the providers it needs.
For example, if your configuration requires the random provider, initialization may download that provider into Terraform’s working data.
It also creates or updates the dependency lock file:
.terraform.lock.hcland creates the .terraform directory.
Conceptually:
Configuration
│
▼
terraform init
│
├── discover dependencies
├── select provider versions
├── install providers
└── create/update lock fileYou normally run init when you begin working with a configuration, and again when changes require reinitialization.
For example, changing provider requirements can require another initialization.
terraform fmt
Terraform configurations can be formatted consistently using:
terraform fmtThis command rewrites Terraform configuration files into Terraform’s standard formatting style.
Formatting is not an infrastructure operation. It does not create or modify your infrastructure.
That distinction matters:
terraform fmt
= modifies configuration formatting
terraform plan
= proposes infrastructure changes
terraform apply
= performs infrastructure changesYou can run terraform fmt frequently while editing.
For a project, it is common to format Terraform files before committing them.
terraform validate
Once the configuration is initialized, you can ask Terraform to check whether the configuration is valid:
terraform validateValidation checks the configuration for syntax and internal consistency problems.
For example, Terraform can detect configuration problems such as malformed blocks or invalid or missing arguments.
A successful validation does not mean Terraform has confirmed that the infrastructure will work exactly as intended.
It means the configuration passes Terraform’s validation rules.
That distinction is important:
validate
│
└── Is this configuration valid?
plan
│
└── What changes would this configuration require?terraform plan
The plan is where Terraform’s declarative model becomes visible.
Run:
terraform planTerraform evaluates the configuration and determines what it expects to change.
A plan might show:
Plan: 1 to add, 0 to change, 0 to destroy.The plan is a proposal. It does not normally make the infrastructure changes itself.
This makes the plan valuable for review.
You can ask:
- Is Terraform creating the resource I expected?
- Is it changing something I did not intend to change?
- Is a resource being replaced?
- Is Terraform going to destroy anything?
- Did a variable have an unexpected value?
A good Terraform workflow treats the plan as something worth reading rather than as an annoying step before apply.
Create, Update, and Replacement
Terraform can make different kinds of changes.
Suppose the configuration initially describes one resource:
Desired configuration
│
▼
ResourceIf the resource does not exist, Terraform may plan to create it.
Later, you change an argument. If the underlying provider supports changing that property in place, Terraform may plan an update.
Sometimes a property cannot be changed in place. Terraform may instead need to:
destroy old resource
↓
create replacement resourceA plan makes this distinction visible.
This is one reason you should not blindly approve plans i.e. a small configuration change does not necessarily imply a small infrastructure change.
terraform apply
After reviewing a plan, you can apply the changes:
terraform applyTerraform normally shows the proposed changes and asks for confirmation.
When you confirm, Terraform performs the operations necessary to bring the infrastructure toward the desired configuration.
A useful mental model is:
configuration
│
▼
plan
│
▼
review
│
▼
apply
│
▼
infrastructureTerraform does not simply execute the text of the configuration as a script. It uses its evaluation and planning process to determine the operations required.
A Hands-On Change
Create a directory:
mkdir terraform-workflow
cd terraform-workflowCreate main.tf:
terraform {
required_providers {
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
}
}
provider "random" {}
resource "random_pet" "name" {
length = 2
separator = "-"
}
output "generated_name" {
value = random_pet.name.id
description = "The generated name."
}Initialize:
terraform initFormat:
terraform fmtValidate:
terraform validateCreate a plan:
terraform planApply it:
terraform applyConfirm with:
yesNow change the resource:
resource "random_pet" "name" {
length = 3
separator = "-"
}Run:
terraform planTerraform will calculate a new proposed result.
The important part of this exercise is not memorizing length = 3. It is observing the workflow:
Configuration changed
↓
terraform plan
↓
Terraform evaluates the new desired state
↓
Terraform proposes a changeWhen you are finished:
terraform destroyConfirm the destruction.
terraform destroy
Destroy removes the infrastructure Terraform manages for the configuration.
Run:
terraform destroyTerraform generates a destruction plan and asks for confirmation.
This is deliberately similar to terraform apply.
That is because destroy is not a special magic deletion command. Terraform still needs to determine what managed infrastructure exists and what operations are required to remove it.
The mental model is:
terraform apply
desired state → real infrastructure
terraform destroy
managed infrastructure → removed infrastructureDestroy is especially useful for temporary environments and learning exercises.
Warning
terraform destroy is a real infrastructure operation. Never run it against a configuration until you understand which resources it manages and have reviewed the proposed destruction.
Why Terraform Does Not Run .tf Files Top to Bottom
If you come from a scripting background, you may naturally expect:
line 1
line 2
line 3
line 4Terraform does not work that way.
Terraform configuration describes resources and values. Terraform evaluates that configuration and determines dependencies between things.
For example:
resource "example_network" "main" {
# ...
}
resource "example_server" "web" {
network_id = example_network.main.id
}The server refers to the network’s ID.
Terraform can therefore understand that the server depends on the network.
The important relationship is:
network
│
│ id
▼
servernot:
network block appears before server blockThe first relationship is meaningful to Terraform. File ordering by itself is not.
You will study dependency evaluation in much greater depth later in the course. For now, simply remember that Terraform is declarative rather than a line-by-line provisioning script.
A Useful Daily Workflow
For a normal configuration change, a practical sequence is:
terraform fmt
terraform validate
terraform plan
terraform applyIf the working directory has not been initialized, run:
terraform initbefore validation and planning.
For destructive changes, pay particular attention to the plan.
A useful habit is:
Never treat
terraform planas noise. It is the explanation of what Terraform believes your configuration change means for real infrastructure.
You now have the basic Terraform lifecycle: initialize dependencies, format and validate configuration, generate a plan, apply changes, modify configuration, and eventually destroy the managed infrastructure.
The next chapter looks at the pieces Terraform is actually managing: providers, resources, and the Terraform Registry.