Skip to main content
terraform taint and terraform apply -replace: Force Resource Recreation

terraform taint and terraform apply -replace: Force Resource Recreation

Key Takeaway

Learn terraform taint, terraform untaint, and the modern terraform apply -replace. When to force-recreate resources, with examples for AWS EC2, modules

Table of Contents

Quick Answer

# Modern way (Terraform 1.0+) — recommended
terraform apply -replace="aws_instance.web"

# Legacy way (deprecated but still works)
terraform taint aws_instance.web
terraform apply

Both force Terraform to destroy and recreate a resource on the next apply.

terraform taint vs terraform apply -replace

terraform taint was the original command. As of Terraform v1.0, terraform apply -replace is the recommended alternative:

terraform taintterraform apply -replace
StatusDeprecated (still works)Recommended
StepsTwo commands (taint + apply)One command
Plan previewNo (modifies state immediately)Yes (shows plan first)
Undoterraform untaintCancel the plan
State modificationModifies state before applyOnly modifies during apply

Basic Usage

# Preview the replacement
terraform plan -replace="aws_instance.web"

# Apply the replacement
terraform apply -replace="aws_instance.web"

Output:

  # aws_instance.web will be replaced, as requested
-/+ resource "aws_instance" "web" {
      ~ id            = "i-0abc123def456" -> (known after apply)
      ~ public_ip     = "54.123.45.67" -> (known after apply)
        # (other attributes unchanged)
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Replace Multiple Resources

terraform apply \
  -replace="aws_instance.web" \
  -replace="aws_security_group.web"

Resources in Modules

terraform apply -replace="module.vpc.aws_subnet.public[0]"

Resources with count or for_each

# count index
terraform apply -replace="aws_instance.web[0]"
terraform apply -replace="aws_instance.web[2]"

# for_each key
terraform apply -replace='aws_instance.web["us-east-1"]'

Using terraform taint (Legacy)

Taint a Resource

terraform taint aws_instance.web

Output:

Resource instance aws_instance.web has been marked as tainted.

Verify the Taint

terraform plan
  # aws_instance.web is tainted, so must be replaced
-/+ resource "aws_instance" "web" {

Apply the Replacement

terraform apply

Untaint (Undo)

Changed your mind? Remove the taint before applying:

terraform untaint aws_instance.web

Taint Resources in Modules

terraform taint module.webserver.aws_instance.app
terraform taint 'module.webserver.aws_instance.app[0]'

When to Force-Replace Resources

1. Resource Is in a Bad State

The EC2 instance is running but the application crashed and won’t recover:

terraform apply -replace="aws_instance.app"

Faster than SSH debugging if you have proper user_data/AMI setup.

2. Update Immutable Attributes

Some attributes can’t be changed in place (AMI, launch template). Terraform normally handles this, but if you need to force it:

terraform apply -replace="aws_launch_template.app"

3. Rotate Secrets or Certificates

Force recreation of resources that embed secrets:

terraform apply -replace="aws_iam_access_key.deploy"
terraform apply -replace="tls_private_key.ca"

4. Test Your Provisioning

Verify that your user_data, provisioners, or bootstrap scripts still work:

terraform apply -replace="aws_instance.web"

5. Force Null Resource Triggers

resource "null_resource" "deploy" {
  triggers = {
    version = var.app_version
  }

  provisioner "local-exec" {
    command = "./deploy.sh"
  }
}
terraform apply -replace="null_resource.deploy"

What Happens During Replacement

1. Terraform creates a plan showing the resource will be replaced
2. You approve the plan
3. Terraform DESTROYS the existing resource
4. Terraform CREATES a new resource with the same configuration
5. State is updated with the new resource ID

Important: The default order is destroy-then-create. If you need create-before-destroy (zero downtime), add a lifecycle rule:

resource "aws_instance" "web" {
  # ...
  lifecycle {
    create_before_destroy = true
  }
}

Risks and Precautions

Data Loss

Replacing a resource destroys it. If it has data (EBS volume, database, S3 bucket), that data may be lost:

# DANGEROUS — will destroy the database!
terraform apply -replace="aws_db_instance.production"

Always check what happens to data before replacing stateful resources.

Downtime

Between destroy and create, the resource doesn’t exist. For production services, use create_before_destroy or blue-green deployments.

Dependent Resources

Replacing a resource may trigger changes in dependent resources:

terraform plan -replace="aws_security_group.web"

# Shows:
# aws_security_group.web will be replaced
# aws_instance.web will be updated (security group reference changes)

Always review the full plan before applying.

State Lock

If you’re using remote state, ensure no one else is running Terraform at the same time:

# Check current state lock
terraform force-unlock LOCK_ID  # Only if stuck

Common Errors

“Resource instance not found”

Error: Resource instance aws_instance.web not found in the current state.

The resource doesn’t exist in state. Check with terraform state list.

“Cannot taint a resource within a module”

Use the full module path:

terraform taint module.app.aws_instance.web
# NOT
terraform taint aws_instance.web  # Wrong if it's in a module

Taint + prevent_destroy conflict

Error: Instance cannot be destroyed

The resource has prevent_destroy = true. Remove it first, or use -replace which shows this in the plan.

Hands-On Courses

Learn by doing with interactive courses on CopyPasteLearn:

Conclusion

Use terraform apply -replace="resource.name" to force-recreate resources. It’s the modern replacement for terraform taint — one command, with a plan preview, no premature state modification. Use it for broken instances, secret rotation, immutable attribute updates, and provisioning tests. Always review the plan for data loss and downtime risks before applying.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.