After a provider upgrade, plan wants to replace a live database — diagnose and avoid data loss
You bumped the AWS provider from 4.x to 5.x. Nothing in your config changed, but plan now wants to REPLACE a live RDS (Relational Database Service) instance — a destroy and recreate that would drop all data. Explain likely causes and how you investigate and avoid the data loss, WITHOUT just applying.
# aws_db_instance.main must be replaced
-/+ resource "aws_db_instance" "main" {
~ id = "prod-db" -> (known after apply)
~ engine_version = "14.7" -> "14.10" # forces replacement
# (many unchanged attributes hidden)
}
Plan: 1 to add, 0 to change, 1 to destroy.
Diagnose the cause and give the safe response.
A provider major bump can change which attribute forces replacement — here engine_version now forces a replace. Read the upgrade guide first. Avoid the destroy with ignore_changes or prevent_destroy; if cosmetic, reconcile via -refresh-only. Never apply a live-DB replace blindly.
- ✗Applying a
-/+replace on a stateful resource without investigating - ✗Assuming a provider upgrade can never force a replacement
- ✗Thinking
ignore_changescannot stop a forced replacement
- →How does
create_before_destroyreduce downtime when a replace is unavoidable? - →Why read the provider's upgrade guide before bumping a major version?
A provider major upgrade changes the schema: different defaults, or different logic for which attribute is ForceNew. Here the new provider treats an engine_version change as forcing a -/+ replacement, which would drop the DB.
Investigation and safe response
resource "aws_db_instance" "main" {
# ...
engine_version = "14.10" # align code with the real version
lifecycle {
prevent_destroy = true # guard against an accidental destroy
ignore_changes = [engine_version] # stop this attribute forcing a replace
}
}
terraform apply -refresh-only reconciles state without recreating.
- Read the provider's 4.x -> 5.x upgrade guide to learn what changed.
- Align the code to the live value; if the diff is only cosmetic,
prevent_destroyis a guardrail soapplycannot drop the DB by mistake.
Never apply a -/+ on a live database blindly.