5.2 Apply Changes to Infrastructure
Key Takeaways
- `terraform apply` executes a plan: without a file it generates a new plan and waits for `yes`; `terraform apply tfplan` applies that saved plan and does not generate or confirm a new one.
- `-auto-approve` skips the interactive prompt for a freshly generated plan. Terraform ignores `-auto-approve` when you pass a saved plan, because passing the file is the approval.
- A single apply can create, update, destroy, or replace individual resources as the plan specified, in dependency order and in parallel when the graph allows.
- If apply errors midway, Terraform updates state for what succeeded and does **not** roll back. Fix the cause and apply again.
- `terraform apply -replace=ADDRESS` is the current Terraform 1.12 way to force replacement. `terraform taint` is deprecated—do not treat taint as the current command.
5.2 Apply Changes to Infrastructure
Quick Answer:
terraform applyexecutes a plan. With no file it generates a new plan, promptsDo you want to perform these actions?, and only continues if you typeyes.terraform apply tfplanapplies a saved plan and skips generating or confirming a new one.-auto-approveskips the prompt for a freshly generated plan. A failed apply does not roll back; state records what succeeded. Force a rebuild withterraform apply -replace=ADDRESS, not with the deprecatedterraform taintcommand.
Objective 3e on Terraform Associate (004) is apply changes to infrastructure with Terraform. Terraform 1.12 and HCP Terraform use the same apply semantics. HCP Terraform may run apply in a remote execution environment and store the state for you; it does not invent a different approval model. Someone still reviews a plan, then an apply performs it.
What apply actually does
Official CLI docs: the terraform apply command executes the operations proposed in a Terraform plan. Usage is terraform apply [options] [plan file].
HashiCorp's apply tutorial lists the working sequence for a typical local run:
- Lock the workspace state so another Terraform process cannot modify the same state at the same time.
- Plan — either generate a new plan and wait for approval, or take the saved plan you passed on the command line.
- Execute the planned create, update, destroy, and replace actions through the providers
terraform initalready installed. Independent resources run in parallel (default parallelism is 10). Dependent resources wait for their graph parents. - Write state that snapshots what now exists.
- Unlock state.
- Report the result (
Apply complete! Resources: N added, M changed, K destroyed.) and any outputs.
Apply is not "run all the .tf files from top to bottom." File order is not apply order. The resource graph is.
Two approval paths: interactive versus saved plan
| Invocation | How the plan is chosen | Confirmation |
|---|---|---|
terraform apply | Terraform creates a new execution plan as if you had run terraform plan | Interactive prompt. Only yes approves |
terraform apply tfplan | Terraform executes the saved plan file | No extra confirmation. Passing the file is the approval |
terraform apply -auto-approve | New plan, same as the first row | Prompt skipped. Official warning: make sure nobody is changing infrastructure outside the Terraform workflow |
Saved-plan mode is the automation path. Official docs: when you pass a saved plan file, Terraform performs those operations without prompting. You cannot attach extra planning modes or planning options (-destroy, -refresh-only, -replace, -var) to that invocation. Those flags change which actions Terraform would choose, and the plan file already contains the final decisions. Inspect first with terraform show.
-auto-approve is ignored when you pass a previously saved plan, because Terraform already treats the file as approval. That includes destructive operations. In automation, HashiCorp still wants a human or a policy engine to review a plan before the apply job runs.
-input=false disables interactive prompts, including the approval prompt. Without a saved plan or -auto-approve, apply then fails conservatively rather than assuming you meant yes. That is why CI usually uses either terraform apply tfplan or terraform apply -auto-approve after a reviewed plan, never a bare terraform apply on a headless runner.
Apply can create, update, destroy, or replace — individually
A single apply is not all-or-nothing "create the stack." The plan may mix actions:
- Create a new
aws_s3_bucket.logsthat exists only in configuration. - Update in place
aws_instance.webbecauseinstance_typechanged. - Destroy
aws_security_group.oldbecause you deleted its resource block. - Replace
aws_instance.dbbecauseamiis force-new, or because you passed-replace.
Outputs can change in the same apply. Data sources are read during the plan/refresh, not "applied" as managed objects.
On HCP Terraform, the same mixed plan appears in the run UI. Confirming the run is the hosted equivalent of typing yes. Policy checks (Sentinel or OPA on HCP Terraform / Terraform Enterprise) evaluate the plan before apply is allowed to start.
Partial apply and errors
Official apply tutorial: when Terraform encounters an error during an apply step, it logs the error, updates the state file with any changes that already succeeded, unlocks state, and exits. Terraform does not support automatically rolling back a partially completed apply.
After you fix the cause—bad credentials, a click-ops engineer deleted the bucket the plan assumed still existed, a quota error, a provider bug—you apply again. The next plan sees what state already recorded and only proposes the remaining work (plus any new drift).
Exam language: "state reflects what succeeded." Do not pick "Terraform deletes everything it created in this run" or "state is discarded so you can start over." Those answers describe a transaction system Terraform is not.
A related trap is applying a stale saved plan after someone changed the real world. The saved plan still thinks the bucket exists. Apply fails on that step; earlier successful steps in the same plan stay applied and stay in state.
Refresh-only apply
terraform apply -refresh-only (Terraform v0.15.4+) creates and, after approval, applies a plan whose only goal is to update state and root-module outputs to match remote objects. Use it after intentional out-of-band changes that you want Terraform to remember, not immediately undo. It is the apply-side counterpart of terraform plan -refresh-only.
Normal apply still refreshes first (unless -refresh=false), then enforces configuration. Refresh-only apply refreshes and stops there.
Force replacement: -replace, not taint
terraform taint is deprecated. Official taint docs: instead, add the -replace option to terraform apply.
terraform apply -replace="aws_instance.example[0]"
Why HashiCorp prefers -replace on Terraform 1.12: the replacement appears in the plan you are about to approve, so you see the destroy-and-create (or create-and-destroy) before anything externally visible happens. terraform taint only flipped a bit in state. Another operator could plan against that tainted object before you reviewed the blast radius.
On 004, if a VM is degraded and the configuration did not change, the current command is terraform apply -replace=ADDRESS. You may also pass -replace to terraform plan. You will still see -/+ or +/- in the plan. Do not answer with terraform taint as the current workflow.
Worked scenario
A platform team reviews terraform plan -out=tfplan in CI. The plan is 1 to add, 1 to change, 0 to destroy: a new IAM role and an in-place tag update. A reviewer approves the pull request. The deploy job runs terraform apply tfplan. Terraform does not invent a second plan, does not ask yes, and performs exactly those two actions. Mid-apply, the IAM API returns a throttling error after the tag update already succeeded. State now contains the new tags and does not contain the role. The job fails. The engineer fixes nothing in HCL, waits out the throttle, and applies again. The next plan only creates the role.
If that same team had typed terraform apply -auto-approve on the deploy runner without a saved plan, Terraform would have generated a new plan at deploy time. A last-minute commit or a console edit could make that plan differ from what the reviewer saw. That is why HashiCorp documents saved plans as the automation path.
Exam traps for objective 3e
terraform apply tfplandoes not prompt for a new plan. Passing the file is approval.-auto-approveis not required when applying a saved plan, and it is ignored if you pass one.- Apply can destroy resources. It is not create-only.
- Partial failure is not an automatic rollback.
- Do not pick
terraform taintas the current replace workflow. Useterraform apply -replace=ADDRESS. -input=falsewithout a saved plan or-auto-approvedoes not silently apply; it fails closed.
Official references: terraform apply command, Apply Terraform configuration, and the deprecated terraform taint page that points at -replace.
A pipeline runs terraform apply tfplan after a reviewer inspected that saved plan. What happens?
Terraform creates two of three planned resources, then the third API call fails. What is the official recovery model?
An EC2 instance is degraded. The HCL did not change. On Terraform 1.12, what is the current way to force a replacement?