Let’s examine a real-world example where Terragrunt shines. Imagine managing a multi-environment AWS infrastructure with shared components:
Root terragrunt.hcl
remote_state {
backend = “s3”
config = {
bucket = “acme-terraform-states”
key = “${path_relative_to_include()}/terraform.tfstate”
region = “us-east-1”
encrypt = true
dynamodb_table = “terraform-locks”
}
}
Pass common variables to all child Terragrunt configurations
inputs = {
company_name = “ACME”
aws_region = “us-east-1”
}
Common AWS provider for all modules
generate “provider” {
path = “provider.tf”
if_exists = “overwrite_terragrunt”
contents = <<EOF
provider “aws” {
region = “${local.aws_region}”
default_tags {
tags = {
Environment = “${local.environment}”
Terraform = “true”
Project = “${local.project}”
}
}
}
EOF
}
Environment-specific configuration:
environments/production/terragrunt.hcl
include {
path = find_in_parent_folders()
}
locals {
environment = “production”
project = “main-app”
}
inputs = {
environment = local.environment
instance_types = [“m5.large”]
high_availability = true
backup_retention = 30
}
Component-specific configuration:
environments/production/database/terragrunt.hcl
include {
path = find_in_parent_folders()
}
dependency “vpc” {
config_path = “../vpc”
Configure mock outputs for the vpc module to allow
database plan to work even when VPC isn’t created yet
mock_outputs = {
private_subnets = [“subnet-123”, “subnet-456”]
vpc_id = “vpc-123”
}
}
terraform {
source = “github.com/terraform-aws-modules/terraform-aws-rds?ref=v3.4.0”
}
inputs = {
identifier = “production-db”
Get values from the VPC module output
subnet_ids = dependency.vpc.outputs.private_subnets
vpc_security_group_ids = [dependency.vpc.outputs.database_security_group_id]
engine = “postgres”
engine_version = “13.4”
instance_class = “db.m5.large”
allocated_storage = 100
name = “appdb”
username = “dbadmin”
password = “get_from_parameter_store”
backup_retention_period = 30
Additional RDS parameters…
}
This example demonstrates several Terragrunt strengths:
- Consistent remote state configuration
- Environment-specific variables
- Dependencies between components
- Code reuse through centralized modules
Organizations concerned with managed cloud security services appreciate how Terragrunt helps maintain security standards across environments through configuration inheritance.