Many older Terraform examples rely on null_resource to trigger actions or force infrastructure replacement. The pattern works, but it depends on the external null provider and often mixes execution logic with infrastructure definitions.
Terraform introduced terraform_data to solve this problem.
The key idea is simple. Terraform only reacts to values it can track in state. The terraform_data resource stores a value such as a version number or configuration revision. When that value changes, Terraform detects the difference during the plan phase.
That change can then trigger a controlled replacement using the lifecycle argument replace_triggered_by.
Instead of hiding automation logic inside a fake resource, the configuration now creates a clear causal chain:
- A variable changes
terraform_datarecords the change in state- Dependent resources replace in response
The result is a plan that shows why a replacement occurs rather than leaving it implicit.
Another common use case for null_resource was running scripts through provisioners. terraform_data can host those provisioners as well, but this should remain a last-resort pattern because Terraform cannot model the side effects of external commands.
The practical takeaway: treat terraform_data as a control signal, not as infrastructure.
If you are modernizing Terraform configurations, replacing null_resource with terraform_data produces cleaner plans, fewer provider dependencies, and clearer infrastructure intent.

