At that point, you’re conceding the exact limitation I was pointing out. Terraform can't handle truly dynamic infrastructure changes within a single plan because its execution model is declarative, not imperative. Saying "nobody would think you could" just acknowledges that Terraform lacks the flexibility of real code—because if it were actual code, you'd be able to handle this inline rather than orchestrating multiple runs with external tools.
Yes, you can manage this with separate state files and a structured apply sequence (e.g., using Terragrunt), but that’s just adding more scaffolding to work around Terraform’s inability to express dynamic logic. That’s infrastructure orchestration, not infrastructure as code.
The fact that we have to rely on external tools or multi-step workflows to accomplish something that would be trivial in a real programming language just reinforces the point: Terraform isn’t really "code" in the traditional sense.
The point is terraform can do it, and it does it well. Just because you don't want to use Terraform properly doesn't mean it's bad at what it does.
Using "a real programming language" to do the infra still has to solve the same issues faced by terraform. Using a programming language to define infra doesn't solve the auto scaling DNS issue, for example, you'll be using lambdas to create the dns either way. It also doesn't inherently solve coordination of the resource deployment, you still need to organise your code into modules and ensure the order of execution.
If you think Terraform is the problem here you're blaming the tool for a failure of process and understanding
The core issue isn't whether Terraform can do it—it's how it does it. You're describing a workflow that requires multiple state files, external tools like Terragrunt, and sequential terraform apply runs to work around the fact that Terraform itself lacks imperative, runtime-driven logic. That’s not "using Terraform properly"—that’s compensating for its limitations.
And sure, using a general-purpose language doesn’t magically eliminate coordination problems, but it does give you far more control. If I were using something like Pulumi or CDK, I wouldn’t need to hack around Terraform’s static graph by splitting state files and manually sequencing deployments. I could express logic directly in code—dynamically querying instance IDs, handling autoscaling changes, and updating DNS records inline, without requiring an entirely separate execution step.
So no, this isn't a "failure of process and understanding"—it's just recognizing that Terraform’s declarative model is great for static infrastructure but falls short when dealing with truly dynamic scenarios. If you think its workflow is fine, that’s cool—but don’t pretend it doesn’t have real limitations just because you've built processes to work around them.
Yes, if you use your tools poorly, it will turn out badly.
I run infra that has dynamic scaling provisioned via Terraform. Guess what, we auto-scale from hundreds to thousands of boxes a day dynamically managed through TF and we have had no issues, since we bothered to figure out how to do it properly.
I don’t doubt that you’ve made Terraform work for your needs. The point isn't that Terraform can't be used for dynamic infrastructure—it's that doing so requires workarounds like pre-split state files, sequential applies, or additional tooling like Terragrunt. That’s not the same as having a truly dynamic system where resources can be created and modified in response to real-time conditions without external orchestration.
Terraform works well for many cases, but the fact that you had to “figure out how to do it properly” kind of proves the point—it’s not inherently designed for dynamically changing infrastructure within a single apply cycle. If it were, you wouldn’t need external coordination to handle something as simple as "create DNS records for all instances, even if the number changes at runtime."
At the end of the day, Terraform is great for declaring infrastructure, but it lacks the flexibility of programming infrastructure. If you’re happy with the trade-offs, great—but let’s not pretend those trade-offs don’t exist.
If your instances are created by Terraform itself, sure, you can use for_each with a data source to define DNS records dynamically. But if the instances are created dynamically outside of Terraform—such as through an auto-scaling group—then Terraform's static plan model becomes a problem.
Terraform data sources can read existing infrastructure, but they don't automatically trigger new resource creation based on real-time changes. That means your DNS records won't update unless you manually run terraform apply again, and they won’t be part of a single apply cycle. In contrast, a real programming language could handle this as a continuous process, responding to infrastructure changes in real-time.
So yes, you can query instances with a data source and use for_each—but unless you’re running Terraform repeatedly to catch changes, your DNS records won’t reflect real-time scaling events. That’s the exact limitation I’m talking about: Terraform isn’t imperative, it’s declarative, and it doesn’t react dynamically at runtime without external orchestration.
You keep saying using multiple state files is a hack and a workaround. It's not, it's how you're supposed to use the tool, and it's a good way to think about and manage infrastructure.
Applying changes in a structured, staged approach via that separation is a great way to avoid issues that will be obfuscated when managing infrastructure in other ways.
Yes, you can manage this with separate state files and a structured apply sequence (e.g., using Terragrunt), but that’s just adding more scaffolding to work around Terraform’s inability to express dynamic logic. That’s infrastructure orchestration, not infrastructure as code.
The fact that we have to rely on external tools or multi-step workflows to accomplish something that would be trivial in a real programming language just reinforces the point: Terraform isn’t really "code" in the traditional sense.