This article focuses on an infrastructure as code tool, terraform, and helps developers quickly and confidently scale your cloud deployments, and also easily maintain and manage the infrastructure of their projects.
1. IAC Tool — Terraform
Terraform is an IAC tool created by Hashicorp, and it defines infrastructure (cloud, on-prem, SaaS) in declarative .tf files and provisions it. Terragrunt is a thin wrapper around Terraform, created by Gruntwork. It helps with managing Terraform projects at scale (especially with multiple environments, accounts, or modules).
1.1 Terraform
- Core features:
 - Uses providers (AWS, Azure, GCP, etc.).
 - Manages resources (VMs, databases, networks, etc.).
 - Maintains state (in .tfstate files).
 - Supports modules for reusability.
 
✅ Best when: you want a direct, provider-backed tool to define and manage infrastructure.
1.2 Terragrunt
- Core features:
 - DRY (Don’t Repeat Yourself): Centralizes common Terraform code and variables.
 - Handles remote state management easily (e.g., S3 + DynamoDB for AWS).
 - Manages multiple Terraform modules (e.g., prod, dev, staging).
 - Dependency management: ensures some stacks are applied before others.
 - Adds a standard project structure.
 
✅ Best when: you have many environments, modules, or teams and need orchestration and consistency.
1.3 Terraform and Terragrunt
Terraform is the engine: it does the actual work of provisioning.
Terragrunt is the orchestrator: it helps you run Terraform consistently across many environments with less repetition.
1.4 When to use what
Small project, single environment → Terraform only is fine.
Large project, multiple environments/accounts → Terraform + Terragrunt gives better structure and automation.
2. Example of Usage
2.1 Folder Structure
A common pattern is:
1  | infra-live/  | 
infra-modules/ → reusable Terraform modules (network, app, etc.)
infra-live/ → Terragrunt configs per environment that call the modules
2.2 Root terragrunt.hcl
This defines common settings (remote state + provider configs) for all environments:
1  | # infra-live/terragrunt.hcl  | 
👉 What this does:
Stores Terraform state in an Azure Storage Account (remote backend).
Generates a provider block so we don’t need to repeat it in every module.
2.3 Module Example — network
1  | # infra-modules/network/main.tf  | 
2.4 Terragrunt Environment Config — Dev Network
1  | # infra-live/dev/network/terragrunt.hcl  | 
👉 Breakdown:
include {}→ pulls in root terragrunt.hcl (so backend/provider settings apply).terraform { source = ... }→ points to the Terraform module.inputs {}→ values for this environment.
2.5 Terragrunt Environment Config — Dev App
1  | # infra-live/dev/app/terragrunt.hcl  | 
👉 Breakdown:
Declares dependency on network (so VNet is created first).
Uses same provider/backend from root.
Environment-specific app name.
2.6 Running Terragrunt
Commands are the same as Terraform but scoped:
1  | cd infra-live/dev/network  | 
Or run for all modules in an environment:
1  | cd infra-live/dev  | 
3. 🔑 Key Syntax & Behavior
include {}→ inherit root config (keeps DRY).terraform { source = ... }→ points to a reusable Terraform module.inputs = {}→ variables passed to the module.dependencies {}→ ensures correct order across stacks.remote_state {}→ centralizes state storage in Azure.generate {}→ dynamically writes files (like provider.tf).