4.1 The Terraform Write–Plan–Apply Workflow
Key Takeaways
- After you write configuration, HashiCorp's official core workflow is Initialize → Plan → Apply
- Write is the first human step; terraform destroy is a convenience alias for terraform apply -destroy, so it is still a plan-to-delete
- You cannot run terraform plan or terraform apply until terraform init has succeeded in that working directory
- terraform plan -out FILE saves an execution plan; terraform apply FILE performs exactly those actions and is the automation-safe path
- terraform workspace isolates extra state files in one CLI directory; an HCP Terraform workspace is a separate collection with its own configuration, variables, state, and run history
4.1 The Terraform Write–Plan–Apply Workflow
Quick Answer: Write HCL first. Then run
terraform init,terraform plan, andterraform apply— in that order.terraform destroyisterraform apply -destroy: it still builds a plan whose goal is to delete managed objects. Localterraform workspacenames extra state files in one directory. An HCP Terraform workspace is a different product concept with its own configuration, variables, state, and run history.
Objective 3a on Terraform Associate (004) asks you to describe the Terraform workflow on Terraform 1.12. HashiCorp's CLI tutorials state the core workflow as three commands after you have written configuration: Initialize, Plan, and Apply. The exam also expects you to place Write at the front, explain how destroy fits, refuse to plan before init, describe saved plans, and keep CLI workspaces separate from HCP Terraform workspaces.
Official references: Create a Terraform plan and the Terraform CLI commands index (init, plan, apply, destroy, workspace).
Why this objective appears on 004
Most production incidents in this chapter are workflow mistakes, not missing HCL arguments. Someone applies from a laptop that never ran init. Two engineers apply the same terraform.tfstate. A candidate treats terraform workspace new staging as if it created an HCP Terraform workspace with RBAC. A pipeline runs terraform apply without a saved plan and applies a different change than the one reviewers approved. Objective 3a is HashiCorp checking that you can name the official order and the collaboration rules around it.
Write is the first human step
The published phrase is "three main steps after you have written your Terraform configuration." Write is still part of the workflow you must be able to describe:
- Write — author
.tf/.tf.jsonfiles (and optional.tfvars) that declare the desired infrastructure. - Initialize —
terraform initprepares the working directory. - Plan —
terraform planpreviews create, update, and destroy actions. - Apply —
terraform applyexecutes a plan.
Write is a human (or generator) step. Init, plan, and apply are CLI steps. You do not skip Write by running apply in an empty directory, and you do not skip Init by running plan against a freshly cloned repo.
A first root module is ordinary HCL. Nothing here is special syntax — the workflow is what 3a tests:
terraform {
required_version = ">= 1.12.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "logs" {
bucket = "app-logs-004-example"
}
On a new clone the next commands are:
terraform init
terraform plan
terraform apply
terraform apply with no plan file generates a new plan, prints it, and prompts yes before changing anything. That is convenient locally. It is not the same as applying a file you already reviewed.
flowchart LR
Write["Write HCL"] --> Init["terraform init"]
Init --> Plan["terraform plan"]
Plan --> Apply["terraform apply"]
Apply --> Destroy["terraform destroy<br/>apply -destroy"]
Plan -.->|"-out FILE"| Saved["Saved plan file"]
Saved --> Apply
Initialize, then plan, then apply
| Step | Command | What it does | Touches real infrastructure? |
|---|---|---|---|
| Write | Editor / VCS | Declares desired state in HCL | No |
| Initialize | terraform init | Backend, modules, provider plugins, lock file | No (unless the backend itself must be created) |
| Plan | terraform plan | Refresh + proposed actions | Reads remote objects; does not create or destroy |
| Apply | terraform apply | Executes a plan | Yes |
| Destroy | terraform destroy or terraform apply -destroy | Plan whose goal is an empty state | Yes, after approval |
You cannot plan before init. terraform plan and terraform apply need the backend initialized, the module tree installed, and provider plugins present. A fresh git clone has .tf files and usually .terraform.lock.hcl. It does not have .terraform/. Until init succeeds, other workflow commands error and tell you to initialize.
HashiCorp documents what plan does by default:
- Read already-existing remote objects so state is current.
- Compare configuration to prior state.
- Propose actions that would make remote objects match configuration.
plan alone does not carry those actions out. apply does.
Saved plans (-out)
terraform plan -out=tfplan
terraform show tfplan
terraform apply tfplan
-out=FILE writes an execution plan to disk. Passing that file to terraform apply runs exactly those actions and does not prompt for another yes. HashiCorp documents this two-step path as the automation workflow: reviewers (or a pipeline) inspect one plan, then apply that artifact later, even on another machine.
Without -out, terraform plan is a speculative plan — a preview with no intent to apply that exact object. Useful on a feature branch. Not a guarantee that tonight's apply will match this afternoon's printout, because the world and the configuration can change in between.
Exam-level rules for saved plans:
- The file is not human-readable; use
terraform showorterraform show -json. - Plan files can contain sensitive values. Never commit a plan file to version control.
- A saved plan records the Terraform version that created it. Apply it with a compatible CLI.
- On HCP Terraform,
terraform plan -outcan store a reference to a remote run rather than a full local binary. The idea is the same: apply the reviewed plan, not a newly computed one. terraform applywith no file is automatic plan mode: new plan, prompt, then execute. That is fine on a laptop. It is the wrong default when you already approved a saved plan.
Destroy is a plan-to-delete
terraform destroy is documented as a convenience alias for:
terraform apply -destroy
It does not skip planning. Terraform still builds an execution plan whose goal is to destroy every remote object it manages and leave an empty state, then asks you to approve. To preview without executing:
terraform plan -destroy
That is destroy mode, one of the alternative planning modes (the other common one is -refresh-only). Destroy mode is mutually exclusive with normal mode. Removing a resource block and running a normal plan / apply is how you delete one object as part of a desired-state change. destroy is how you deprovision the whole configuration, typical for ephemeral labs.
terraform destroy does not edit your .tf files. After a destroy, the same configuration can apply again and recreate the stack.
Local CLI workspaces are not HCP Terraform workspaces
004 tests this distinction. The word "workspace" appears in two products.
Terraform CLI terraform workspace | HCP Terraform workspace | |
|---|---|---|
| What it is | Another state file attached to the same working directory and configuration | A named collection that behaves like a separate working directory |
| Required? | No. Every directory starts with default | Yes. You cannot manage resources in HCP Terraform without at least one workspace |
| Contains | Isolated state (terraform.tfstate.d/<name>/ locally, or a backend key per name) | Configuration, variables, state, credentials, run history, settings, RBAC |
| Switch with | terraform workspace select | HCP UI, API, or CLI integration that maps this directory to a remote workspace |
| Typical use | A quick extra copy of one config (often a feature-branch sandbox) | The unit of remote state, remote execution, and team permissions |
terraform workspace list
terraform workspace new staging
terraform workspace select default
terraform workspace delete staging
CLI workspaces share one configuration and one backend. They are "technically equivalent to renaming your state file" plus some safety. They are a poor isolation boundary when staging and production need different credentials. HashiCorp's own CLI workspace page says to use separate configurations and backends (or separate HCP workspaces) for that.
An HCP Terraform workspace is required, is a major RBAC object, and stores the configuration (VCS or uploaded), workspace variables, state versions, and run logs. When you connect the CLI with a cloud block, terraform workspace can select which remote HCP workspace this directory talks to. That mapping does not make the two concepts the same thing.
Collaboration: do not apply the same local state from two laptops
Local terraform.tfstate is a file on one disk. If two engineers copy the repo, both apply, and both write that file, you get split-brain state: each laptop thinks it owns the real objects. State locking exists to reduce races, but a local backend is not a team workflow. HashiCorp's guidance is a remote backend or HCP Terraform so there is one state, one lock, and (on HCP) a serialized run queue.
Practical 004 answers:
- One engineer, one laptop, local state — acceptable for a tutorial.
- A team — remote state or HCP Terraform, not two copies of
terraform.tfstate. - HCP Terraform remote execution runs
init/plan/applyon disposable VMs using that workspace's configuration, variables, and state. Your laptop is not the executor.
Scenario: the Friday apply
Ava writes an aws_instance change and opens a pull request. CI runs terraform init then terraform plan -out=tfplan and posts terraform show for review. After merge, the pipeline runs terraform apply tfplan on the same configuration commit. That is the official saved-plan workflow.
Ben instead pulls main on his laptop, skips init after a provider constraint change, and runs terraform apply. Plan fails until init succeeds. If he had applied yesterday's local state while Ava applied from HCP Terraform against the same account, they would be fighting over objects with two sources of truth.
004 traps for objective 3a
- The official core workflow after Write is Init → Plan → Apply, not Apply-first and not Format-first.
- You cannot
planorapplybefore a successfulinit. destroystill plans; it is notrm terraform.tfstate.terraform workspaceis not an HCP Terraform workspace.- Do not commit saved plan files.
- Two laptops sharing local state is not collaboration.
After you write Terraform configuration, what is the official core CLI workflow HashiCorp documents for Terraform 1.12?
On Terraform Associate (004), how do Terraform CLI workspaces differ from HCP Terraform workspaces?
A teammate emails you a file produced by terraform plan -out tfplan. What is the correct next action in the official saved-plan workflow?