Understanding Replacement

Scenario: An engineer changes what looks like one harmless field on a certificate resource, and the resulting plan shows destroy-then-create - turning a small config edit into real customer-facing downtime nobody expected.

You met the concept of replacement briefly back in Module 2, when learning to read plan symbols. Now let's understand why it happens: every attribute a provider exposes on a resource is either editable in place, or marked by the provider as requiring replacement - meaning the underlying real-world object simply cannot have that particular setting changed after creation (a common example: a certificate's common_name, or a database engine version on some providers). When you change one of those attributes, Terraform has no choice but to destroy the existing object and create a brand-new one to reflect the new value, because there's no "update" operation the real API supports for that field.

Plan symbols distinguish which kind of replacement will happen, and the distinction matters enormously for availability: -/+ (destroy-then-create, the default) means the old object is gone before the new one exists - if that object serves live traffic, there's a real window with nothing serving requests at all. +/- with create_before_destroy set (next section) instead builds the new object first, so both briefly coexist, before removing the old one - much safer for anything user-facing, but it requires the object type to support two instances briefly coexisting (unique names, no conflicting global settings) or the create step itself will fail. The habit to build here: never judge a plan's risk by how many lines changed - always trace why a specific replacement is being proposed, and check the reason.

Analogy: Replacing infrastructure is like moving house because a landlord won't let you renovate one specific wall. Building and moving into the new house before giving up the old one avoids a period of homelessness in between - but only works if you can genuinely afford to hold both addresses at once, even briefly; if you can't, you have no choice but to vacate the old place first and accept the gap.

A worked configuration

resource "fakecloud_certificate" "edge" {
  common_name = "api.example.test"
  lifecycle { create_before_destroy = true }
}

Before approving any plan containing a replacement, verify a few things concretely: does the target account have enough quota headroom to briefly hold two instances of this object at once (for create_before_destroy)? Will any uniqueness constraint (a name, a DNS record) collide between old and new? Is there a real traffic-cutover and health-check mechanism, or will the new object just silently exist without receiving traffic? What's the rollback path if the new object comes up unhealthy? Note explicitly: create_before_destroy on its own is not automatically zero-downtime - it avoids the total outage window, but consumers of the old object (load balancers, DNS, other resources referencing its ID) still need their own controlled cutover logic to actually benefit from the overlap.

Common mistakes in production

Goal: Treat the plan as a change contract: understand every create, update, replacement, and destroy before approving it. Reinforce this lesson in the tf-certificate-renewal Terraform lab. Open /labs/terraform and choose slug tf-certificate-renewal; the lab runs real Terraform against the offline FakeCloud provider.