Terraform -replace, taint and -target: Recreate or Limit Resources Safely
Recreate a resource or limit a run #
Sometimes Terraform thinks that a resource is fine but you know it is not: an instance with a broken configuration, a corrupted node, a failed provisioner. Other times you want to apply only part of the configuration. Three tools exist, and the first is the safest.
-replace: force recreation #
$ terraform plan -replace=aws_instance.web
$ terraform apply -replace=aws_instance.web
The plan shows the resource as # aws_instance.web will be replaced, as requested and, since it goes through the normal plan, you can review exactly what will be destroyed and created before confirming. For resources with count or for_each, quote the address:
$ terraform apply -replace='aws_instance.web[1]'
$ terraform apply -replace='aws_subnet.private["b"]'
You can repeat the flag to replace several resources.
taint and untaint: the old way #
terraform taint marks a resource in the state as damaged, so the next apply replaces it:
$ terraform taint aws_instance.web
$ terraform untaint aws_instance.web
It is deprecated in favor of -replace. The problem with taint is that it changes the state immediately and without a plan, so a teammate might apply while the mark is there without realizing it. Use -replace instead.
A provisioner failure (provisioners) still taints a resource automatically.
-target: apply only part of the graph #
$ terraform plan -target=module.network
$ terraform apply -target=aws_security_group.web
-target limits the plan to the resource and what it depends on. It is useful in emergencies, for example to fix a broken resource when the rest of the configuration has an error, or to create a resource that a for_each depends on (see common errors).
Terraform itself warns that it is for exceptional use. The risks:
- The state and the code can diverge, because other resources that should change are skipped.
- It skips dependents, so you may leave the infrastructure in an inconsistent state.
- It becomes a habit that hides structural problems, such as a state that is too big (project structure).
Run a full plan afterwards to confirm that nothing remains. OpenTofu 1.9 and later also has -exclude, the opposite option, to leave out resources.
Other targeted operations #
| Goal | Command |
|---|---|
| Update the state without changing infrastructure | terraform apply -refresh-only |
| Destroy one resource | terraform destroy -target=aws_instance.web |
| Stop managing a resource without deleting it | removed block (guide) |
| Rename in state | moved block |
| Ignore changes made elsewhere | ignore_changes (lifecycle) |
Recreating without downtime #
If the resource serves traffic, use create_before_destroy in its lifecycle so the new one exists before the old one is deleted. With Auto Scaling, prefer an instance refresh over replacing instances by hand.
In CI/CD #
Avoid -target in pipelines. Apply the saved plan of the whole configuration (GitHub Actions). Use -replace only through a reviewed manual workflow.