All skills
Skillintermediate

Terragrunt Common Generation Patterns

This reference provides common patterns and code examples for generating Terragrunt configurations. Use these patterns as building blocks when creating new Terragrunt resources.

Claude Code Knowledge Pack7/10/2026

Overview

Terragrunt Common Generation Patterns

Overview

This reference provides common patterns and code examples for generating Terragrunt configurations. Use these patterns as building blocks when creating new Terragrunt resources.

Include syntax standard: Use find_in_parent_folders("root.hcl") for new projects. Only use find_in_parent_folders() when the repository intentionally keeps a legacy root file named terragrunt.hcl.

Root Configuration Patterns

Pattern 1: Basic Root with S3 Backend

Use when: Starting a new Terragrunt project with AWS S3 backend

# root.hcl (modern root file name)
remote_state {
  backend = "s3"
  config = {
    bucket         = "company-terraform-state"
    key            = "${path_relative_to_include()}/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite_terragrunt"
  }
}

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <= 1.6.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

provider "azurerm" {
  features {}
  subscription_id = var.azure_subscription_id
}

provider "google" {
  project = var.gcp_project
  region  = var.gcp_region
}
EOF
}

Child Module Patterns

Pattern 1: Simple Module with No Dependencies

Use when: Creating standalone infrastructure component

# modules/vpc/terragrunt.hcl
include "root" {
  path = find_in_parent_folders("root.hcl")
}

terraform {
  source = "tfr:///terraform-aws-modules/vpc/aws?version=5.1.0"
}

inputs = {
  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["us-east-1a", "us-east-1b", "us-east-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
  enable_vpn_gateway = false

  tags = {
    Name = "my-vpc"
  }
}

Pattern 2: Module with Single Dependency

Use when: Creating a resource that depends on another module's outputs

# modules/rds/terragrunt.hcl
include "root" {
  path = find_in_parent_folders("root.hcl")
}

terraform {
  source = "tfr:///terraform-aws-modules/rds/aws?version=6.1.0"
}

dependency "vpc" {
  config_path = "../vpc"

  mock_outputs = {
    vpc_id             = "vpc-mock123"
    database_subnet_ids = ["subnet-mock1", "subnet-mock2"]
  }

  mock_outputs_allowed_terraform_commands = ["validate", "plan", "destroy"]
}

dependency "security_group" {
  config_path = "../security-groups/database"

  mock_outputs = {
    security_group_id = "sg-mock123"
  }

  mock_outputs_allowed_terraform_commands = ["validate", "plan", "destroy"]
}

inputs = {
  identifier = "mydb"
  engine     = "postgres"

  vpc_security_group_ids = [dependency.security_group.outputs.security_group_id]
  db_subnet_group_name   = dependency.vpc.outputs.database_subnet_group_name

  allocated_storage = 20
  instance_class    = "db.t3.micro"
}

Pattern 3: Module with Multiple Dependencies

Use when: Creating complex infrastructure with multiple upstream dependencies

# modules/eks/terragrunt.hcl
include "root" {
  path = find_in_parent_folders("root.hcl")
}

terraform {
  source = "tfr:///terraform-aws-modules/eks/aws?version=19.15.0"
}

dependencies {
  paths = ["../vpc", "../security-groups", "../iam-roles"]
}

dependency "vpc" {
  config_path = "../vpc"

  mock_outputs = {
    vpc_id             = "vpc-mock"
    private_subnet_ids = ["subnet-1", "subnet-2"]
  }
  mock_outputs_allowed_terraform_commands = ["validate", "plan"]
}

dependency "security_groups" {
  config_path = "../security-groups"

  mock_outputs = {
    cluster_security_group_id = "sg-mock"
  }
  mock_outputs_allowed_terraform_commands = ["validate", "plan"]
}

dependency "iam" {
  config_path = "../iam-roles"

  mock_outputs = {
    cluster_role_arn = "arn:aws:iam::123456789012:role/mock-role"
  }
  mock_outputs_allowed_terraform_commands = ["validate", "plan"]
}

inputs = {
  cluster_name    = "my-eks-cluster"
  cluster_version = "1.28"

  vpc_id     = dependency.vpc.outputs.vpc_id
  subnet_ids = dependency.vpc.outputs.private_subnet_ids

  cluster_security_group_id = dependency.security_groups.outputs.cluster_security_group_id
  iam_role_arn              = dependency.iam.outputs.cluster_role_arn

  enable_irsa = true
}

Pattern 4: Module with Conditional Logic

Use when: Generating configurations with environment-specific variations

# modules/app/terragrunt.hcl
include "root" {
  path = find_in_parent_folders("root.hcl")
}

locals {
  env = get_env("ENVIRONMENT", "dev")

  instance_counts = {
    dev  = 1
    staging = 2
    prod = 3
  }

  instance_types = {
    dev  = "t3.micro"
    staging = "t3.small"
    prod = "t3.medium"
  }
}

terraform {
  source = "../../terraform-modules/app"
}

inputs = {
  environment    = local.env
  instance_count = local.instance_counts[local.env]
  instance_type  = local.instance_types[local.env]

  enable_monitoring = local.env == "prod" ? true : false
  enable_backups    = local.env == "prod" ? true : false

  tags = merge(
    {
      Environment = local.env
      ManagedBy   = "Terragrunt"
    },
    local.env == "prod" ? { CriticalResource = "true" } : {}
  )
}

Environment-Specific Patterns

Pattern 1: Environment Configuration Files

Use when: Managing multiple environments with shared structure

infrastructure/
├── root.hcl                 # Root config (modern)
├── _env/
│   ├── prod.hcl            # Production variables
│   ├── staging.hcl         # Staging variables
│   └── dev.hcl             # Development variables
├── prod/
│   ├── env.hcl -> ../_env/prod.hcl
│   └── vpc/
│       └── terragrunt.hcl
└── staging/
    ├── env.hcl -> ../_env/staging.hcl
    └── vpc/
        └── terragrunt.hcl

_env/prod.hcl:

locals {
  environment = "prod"
  region      = "us-east-1"

  vpc_cidr = "10.0.0.0/16"

  instance_type = "t3.medium"
  min_size      = 3
  max_size      = 10
}

prod/vpc/terragrunt.hcl:

include "root" {
  path = find_in_parent_folders("root.hcl")
}

locals {
  env = read_terragrunt_config(find_in_parent_folders("env.hcl"))
}

terraform {
  source = "tfr:///terraform-aws-modules/vpc/aws?version=5.1.0"
}

inputs = {
  name = "${local.env.locals.environment}-vpc"
  cidr = local.env.locals.vpc_cidr

  azs = ["${local.env.locals.region}a", "${local.env.locals.region}b"]
}

Advanced Patterns

Pattern 1: Dynamic Provider Configuration

Use when: Provider configuration varies by module or environment

# modules/cross-account-resource/terragrunt.hcl
include "root" {
  path = find_in_parent_folders("root.hcl")
}

locals {
  target_account_id = "987654321098"
}

generate "provider_override" {
  path      = "provider_override.tf"
  if_exists = "overwrite"
  contents  = <= 1.3.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"  # Legacy version for compatibility
    }
  }
}
EOF
}

terraform {
  source = "../../terraform-modules/legacy-resource"
}

Stacks Patterns (2025)

Terragrunt Stacks allow you to define infrastructure blueprints that generate unit configurations programmatically. GA since v0.78.0 (May 2025).

Pattern 1: Basic Stack with Units

Use when: Creating a reusable infrastructure blueprint

Catalog units expect values.name as the base resource identifier from each stack unit.

# terragrunt.stack.hcl
loca