Most teams meet Terragrunt at the same moment.
You have a Terraform module that works. You need it in dev, staging and production. So you copy the directory three times, change a few variables, and change the backend block so each copy keeps its state somewhere different.
Then you need a fourth environment. Then a second region. Now you have twelve copies of a backend block that differ only in a path, and you have already fixed the same bug in six of them and forgotten the other six.
That is the problem Terragrunt was built for. Whether it is your problem is a different question.
What is Terragrunt?
Terragrunt is a thin wrapper around Terraform, originally built by Gruntwork. It does not replace Terraform and it does not have its own provider ecosystem. It shells out to Terraform (or OpenTofu) and adds a layer of configuration on top.
You keep writing Terraform modules. What changes is how you deploy them.
What problem does it actually solve?
Four specific ones. It is worth being precise, because most of the arguments about Terragrunt come from people solving different subsets of these.
1. Backend configuration you cannot template
This is the original reason it exists. Terraform's backend block does not accept variables. You cannot write key = "${var.env}/terraform.tfstate". So every environment needs its own hardcoded backend, which means copy and paste.
Terragrunt generates it:
# root terragrunt.hcl, inherited by every child
remote_state {
backend = "s3"
config = {
bucket = "acme-tfstate"
key = "${path_relative_to_include()}/terraform.tfstate"
region = "eu-west-1"
encrypt = true
}
}
One definition. Every environment gets a state path derived from where it sits in the directory tree. Add a fifth environment and there is nothing to copy.
2. Provider configuration repeated everywhere
Same shape of problem. Provider blocks, assume-role configuration, default tags. Terragrunt's generate block writes them into each module at run time, so they live in one place.
3. Dependencies between modules
This is the one people underrate.
Your VPC module outputs subnet IDs. Your database module needs them. Without Terragrunt you either put both in one giant state file, which makes every change risky, or you wire them together with remote state data sources, which is verbose and easy to get wrong.
dependency "vpc" {
config_path = "../vpc"
# Lets 'plan' work before the VPC exists, which matters in CI on a fresh branch
mock_outputs = {
private_subnet_ids = ["subnet-mock"]
}
}
inputs = {
subnet_ids = dependency.vpc.outputs.private_subnet_ids
}
Terragrunt reads that, works out the dependency graph, and applies things in the right order.
4. Running a command across many modules
run-all plan across every module in an environment, in dependency order. If your infrastructure is split into twenty small state files, which is good practice, this is the difference between one command and twenty.
What Terraform can now do on its own
This is where a lot of older comparisons are out of date, so check the current documentation for whichever version you are on rather than trusting any blog post, including this one.
The direction of travel is clear: Terraform has been steadily absorbing parts of what Terragrunt was invented to work around. Workspaces cover some multi-environment cases. Newer orchestration features aim squarely at the multi-module, dependency-ordered problem. Several commercial platforms solve the same problems from the CI side instead.
Two things follow from that.
If you are starting today, evaluate what your Terraform version already does before adding a tool. The gap Terragrunt fills is genuinely smaller than it was in 2019.
If you already run Terragrunt, none of this is a reason to migrate. A working setup that your team understands beats a marginally more standard one that nobody has debugged at 3am.
So do you need Terragrunt?
One number decides it: how many times do you deploy the same module?
One or two times. No. The duplication is a handful of lines. You will spend more time explaining Terragrunt to new engineers than you will ever save.
Three to five times, all similar. Probably not yet. Terraform workspaces or a well-organised directory structure will carry you. Revisit when the copies start drifting.
Six or more, or several regions, or several accounts. Yes, or something equivalent. At that scale the copy-paste is not a style problem, it is a correctness problem, because the copies will diverge and nobody will notice which one is wrong.
Modules that depend on each other across separate state files. Yes, and this is the strongest case. Doing dependency ordering by hand does not scale past a few modules.
What it costs you
Three costs, and the third is the one people miss.
A second tool in the chain. Every engineer now installs and versions two things. Every CI job runs two things. Version compatibility between them becomes something you have to think about.
Indirection. The Terraform that actually runs is not the Terraform you wrote. It is your module plus generated backend and provider blocks plus inherited inputs. Debugging means understanding what Terragrunt produced, and terragrunt render-json becomes a command you use often.
A smaller search space. This is the real tax. When something breaks, you are looking for the intersection of "Terraform" and "Terragrunt" answers, and that intersection is much smaller than either alone. Every senior hire who knows Terraform cold still has to learn your wrapper.
Common questions
Is Terragrunt deprecated? No. It is actively maintained and widely used. The question people are usually asking is whether it is still necessary, and that depends on your Terraform version and your scale.
Can I use Terragrunt with OpenTofu? Yes. Terragrunt is a wrapper, so it can drive either binary. Teams that moved to OpenTofu after the licence change generally kept Terragrunt without much trouble.
Is it a replacement for a CI/CD platform? No, and this trips people up. Terragrunt orchestrates modules. It does not give you approvals, drift detection, policy enforcement, or an audit trail. You still need something around it.
Can I adopt it incrementally? Yes, and you should. Start with one environment, keep the rest as-is, and see whether the indirection is worth it before converting everything.
What about state locking and drift? Unchanged. Terragrunt hands both to Terraform and the backend. If you are fighting configuration drift, Terragrunt does not fix it and does not make it worse.
The short version
Terragrunt solves duplication. If you do not have duplication, it solves nothing and costs you a tool.
The failure mode is not choosing wrong. It is choosing once, at the start, and never revisiting. Teams adopt it for a two-environment project and carry the indirection for years, or refuse it at three environments and are still copy-pasting backends at fifteen.
Re-ask the question every time you add an environment. The answer changes.
DevLift generates Terragrunt and Terraform from a plain-English description, with the backend, provider and dependency wiring produced from your existing structure rather than copied by hand. Changes arrive as a pull request, so your review still runs. Book a walkthrough.