šŸŽ‰ DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

Terragrunt vs Terraform — When to Use Which in 2026

Terragrunt wraps Terraform to solve problems like DRY configs, remote state management, and multi-environment setups. Here's when you actually need it and when you don't.

DevOpsBoysJun 10, 20263 min read
Share:Tweet

Terragrunt is a thin wrapper around Terraform that solves specific problems Terraform doesn't handle well out of the box. You don't always need it — but when you do, it saves hours of config duplication.


What Terraform Doesn't Solve Well

Problem 1: Remote state configuration repeated everywhere

In plain Terraform, every module needs its own backend config:

hcl
# You write this in every module:
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "production/vpc/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

30 modules = 30 copies of this. Change the bucket name? Update 30 files.

Problem 2: DRY configuration across environments

dev, staging, prod often have identical structure with different values. Plain Terraform forces you to either duplicate code or build complex module hierarchies.

Problem 3: Dependency ordering across modules

Running terraform apply in the right order across multiple modules is manual. Forget the order = broken infra.


What Terragrunt Adds

1. DRY remote state — one root config, all modules inherit:

hcl
# terragrunt.hcl (root)
remote_state {
  backend = "s3"
  config = {
    bucket         = "my-terraform-state"
    key            = "${path_relative_to_include()}/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

Every module that includes this root config automatically gets the right state path. Change bucket once, applies everywhere.

2. DRY configurations with include:

hcl
# modules/vpc/terragrunt.hcl
include "root" {
  path = find_in_parent_folders()
}
 
inputs = {
  vpc_cidr = "10.0.0.0/16"
  name     = "production-vpc"
}

No backend configuration needed — inherited from root.

3. Module dependencies:

hcl
# modules/eks/terragrunt.hcl
dependency "vpc" {
  config_path = "../vpc"
}
 
inputs = {
  vpc_id     = dependency.vpc.outputs.vpc_id
  subnet_ids = dependency.vpc.outputs.private_subnet_ids
}

Run terragrunt run-all apply — Terragrunt figures out the dependency graph and applies in the right order automatically.


Typical Terragrunt Directory Structure

infrastructure/
ā”œā”€ā”€ terragrunt.hcl          # Root config — remote state, common vars
ā”œā”€ā”€ production/
│   ā”œā”€ā”€ account.hcl         # AWS account ID, region
│   ā”œā”€ā”€ vpc/
│   │   └── terragrunt.hcl  # VPC inputs
│   ā”œā”€ā”€ eks/
│   │   └── terragrunt.hcl  # EKS inputs, depends on vpc
│   └── rds/
│       └── terragrunt.hcl  # RDS inputs, depends on vpc
└── staging/
    ā”œā”€ā”€ account.hcl
    ā”œā”€ā”€ vpc/
    │   └── terragrunt.hcl  # Same structure, different values
    ā”œā”€ā”€ eks/
    │   └── terragrunt.hcl
    └── rds/
        └── terragrunt.hcl
bash
# Apply everything in production in dependency order:
cd production && terragrunt run-all apply
 
# Apply just one module:
cd production/eks && terragrunt apply
 
# Plan everything:
terragrunt run-all plan

Terragrunt vs Terraform Workspaces

Many teams use Terraform workspaces for multi-environment. Terragrunt and workspaces solve the same problem differently:

Terraform WorkspacesTerragrunt
State separationPer-workspace state filePer-directory state file
Config separationSame .tf files, terraform.workspace variableSeparate terragrunt.hcl per env
VisibilityEasy to accidentally apply to wrong workspaceClear directory structure
ComplexityLowerHigher
DRY remote stateNoYes
Module dependenciesManualAutomatic

Rule of thumb: Workspaces work fine for 2-3 environments with simple infra. Terragrunt pays off when you have 4+ environments or 10+ modules that depend on each other.


When You Don't Need Terragrunt

  • Single environment or simple infrastructure
  • Small team (1-3 people) where duplication is manageable
  • You already have good workspace + module structure
  • You're just getting started with Terraform

Terragrunt adds complexity. Don't introduce it until you feel the pain it solves.


When You Do Need Terragrunt

  • Multiple environments (dev/staging/prod/DR) with identical structure
  • Many modules that depend on each other
  • Remote state config is being duplicated across modules
  • You want run-all to apply your entire infrastructure in one command

Terragrunt with OpenTofu

Terragrunt works with OpenTofu (the open-source Terraform fork) too:

bash
# Use OpenTofu instead of Terraform
export TERRAGRUNT_TFPATH=tofu
terragrunt apply

Learn Terraform and infrastructure management deeply at KodeKloud.

šŸ”§

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments