Terraform Resource Attributes & Dependencies
Discover the importance of resource attributes and dependencies in Terraform. This guide explains how to define, access, and manage these elements to.
Cloud Computing
Learn terraform taint, terraform untaint, and the modern terraform apply -replace. When to force-recreate resources, with examples for AWS EC2, modules
# Modern way (Terraform 1.0+) — recommended
terraform apply -replace="aws_instance.web"
# Legacy way (deprecated but still works)
terraform taint aws_instance.web
terraform applyBoth force Terraform to destroy and recreate a resource on the next apply.
terraform taint was the original command. As of Terraform v1.0, terraform apply -replace is the recommended alternative:
terraform taint | terraform apply -replace | |
|---|---|---|
| Status | Deprecated (still works) | Recommended |
| Steps | Two commands (taint + apply) | One command |
| Plan preview | No (modifies state immediately) | Yes (shows plan first) |
| Undo | terraform untaint | Cancel the plan |
| State modification | Modifies state before apply | Only modifies during apply |
# 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.terraform apply \
-replace="aws_instance.web" \
-replace="aws_security_group.web"terraform apply -replace="module.vpc.aws_subnet.public[0]"# 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"]'terraform taint aws_instance.webOutput:
Resource instance aws_instance.web has been marked as tainted.terraform plan # aws_instance.web is tainted, so must be replaced
-/+ resource "aws_instance" "web" {terraform applyChanged your mind? Remove the taint before applying:
terraform untaint aws_instance.webterraform taint module.webserver.aws_instance.app
terraform taint 'module.webserver.aws_instance.app[0]'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.
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"Force recreation of resources that embed secrets:
terraform apply -replace="aws_iam_access_key.deploy"
terraform apply -replace="tls_private_key.ca"Verify that your user_data, provisioners, or bootstrap scripts still work:
terraform apply -replace="aws_instance.web"resource "null_resource" "deploy" {
triggers = {
version = var.app_version
}
provisioner "local-exec" {
command = "./deploy.sh"
}
}terraform apply -replace="null_resource.deploy"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 IDImportant: 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
}
}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.
Between destroy and create, the resource doesn't exist. For production services, use create_before_destroy or blue-green deployments.
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.
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 stuckError: Resource instance aws_instance.web not found in the current state.The resource doesn't exist in state. Check with terraform state list.
Use the full module path:
terraform taint module.app.aws_instance.web
# NOT
terraform taint aws_instance.web # Wrong if it's in a moduleError: Instance cannot be destroyedThe resource has prevent_destroy = true. Remove it first, or use -replace which shows this in the plan.
Learn by doing with interactive courses on CopyPasteLearn:
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.
Discover the importance of resource attributes and dependencies in Terraform. This guide explains how to define, access, and manage these elements to.
Configure Terraform S3 backend for remote state storage with DynamoDB state locking. Complete setup guide with IAM permissions, encryption, and versioning.
Step-by-step guide to terraform import. Import existing AWS, Azure, and GCP resources into Terraform state. Includes import blocks (Terraform 1.5+)
Fix terraform init S3 backend region mismatch errors. Match the region in your backend config to the actual S3 bucket location. Covers BucketRegionError