Immutable infrastructure, and the replacement nobody planned for
Immutability means a change produces a new resource rather than an edited one, which supports reproducibility when definitions and inputs are controlled. It also means some innocuous-looking edits destroy and recreate a live resource, and knowing which ones is the difference between a routine plan and an outage.
TL;DR: Replace rather than modify, and the environment becomes reproducible, drift-resistant and rollback-friendly. The trap is that the provider decides which attribute changes force replacement, not you, so a one-line diff can destroy a database. Read the plan, not the diff.
Why replacement is the better default
A server patched in place for three years is a unique artifact whose state is the sum of every command anyone has ever run on it, which means nobody can rebuild it and a problem on that host may not reproduce anywhere else. That is the snowflake. The entire reason infrastructure as code exists is to stop producing them.
Replacement limits accumulated host mutations, but reproducibility still needs pinned inputs and a repeatable build. Drift can occur before replacement, so detection remains useful. Promoting the tested image by digest preserves artifact identity; restoring an old image is a rollback only while configuration and durable state remain compatible.
The part that surprises people
The provider decides what forces replacement, not you and not your intent. In Terraform, changing an EC2 instance’s AMI or a subnet’s CIDR can require replacement. Database changes need closer inspection: RDS supports renaming a DB instance identifier in place, with endpoint and availability implications, while other attributes may require replacement. Check the plan produced by the pinned provider version. AWS documents RDS renaming; a name change is not proof of a destroy-and-create operation. The configuration diff can be one line. The plan says must be replaced, in a section people skim.
This is why the review object is the plan and not the code. A generated or hand-written one-line change reads as trivial and states its full intent only in the plan output. A gate that requires explicit acknowledgement for any plan containing a destroy is a useful control in an IaC pipeline, with implementation and review costs.
The lifecycle levers
Three arguments change the behaviour, and each is a decision rather than a workaround:
create_before_destroybuilds the replacement before removing the original, which is how you replace something serving traffic. It requires that both can exist at once, so a resource with a globally unique name needs that handled.prevent_destroyrejects a destroy or replacement while the lifecycle rule remains in the resource configuration. Removing the entire resource block also removes that protection; use provider-side deletion protection and reviewed plans for critical data. Terraform’s lifecycle reference explicitly documents this limit. Correct for a production database, and it will one day block a legitimate change, at which point somebody removes it in a hurry. Use it where an accidental destroy is unrecoverable.ignore_changesstops Terraform reconciling a specific attribute, which is how you coexist with another system that legitimately owns a field. It is also how drift becomes invisible, so each use needs a comment saying who owns that attribute instead.
Where immutability stops being free
Stateful resources are the boundary. Replacing a stateless instance is routine, whereas replacing a database means moving the data, and there is no lifecycle argument that makes that free or fast. So the honest architecture separates the two layers and treats them differently: immutable compute sitting over durable state, with the state layer changed through migrations.
Long-lived caches pull the same way. So do licence-bound hosts, and anything carrying an identity another system depends on, a fixed IP or a specific hostname that somebody wrote into a firewall rule two years ago. Naming those exceptions out loud, instead of pretending the whole estate is cattle, is what turns this from a slogan into something a team can actually apply.
The habit
Read every plan for the words must be replaced. Treat their presence as a different class of change entirely, one that earns a second approver, a maintenance window, or a create-before-destroy path worked out before anyone runs apply. The plan can expose a destructive operation before it happens; review it together with dependencies, data recovery and the expected service interruption.
Self-check
Does replacing a VM from an image guarantee a reproducible environment? No. Verify the image digest, external configuration, startup dependencies and state compatibility. Replacement alone does not control those inputs.