Skip to content
🎉 Terragrunt v1.0 is here! Read the announcement to learn more.

Content Addressable Store (CAS)

Terragrunt supports a Content Addressable Store (CAS) to deduplicate content across multiple Terragrunt configurations. This feature is still experimental and not recommended for general production usage.

The CAS is used to speed up catalog cloning, OpenTofu/Terraform source cloning, and stack generation by avoiding redundant downloads of Git repositories.

To use the CAS, you will need to enable the cas experiment.

You can disable the CAS at any time using the --no-cas flag, even when the experiment is enabled. This flag is available on the run, stack generate, and stack run commands.

When you enable the cas experiment, Terragrunt will automatically use the CAS when cloning any compatible source (Git repositories).

root.hcl
catalog {
urls = [
"git@github.com:acme/modules.git"
]
}
terragrunt.hcl
terraform {
source = "git@github.com:acme/infrastructure-modules.git//vpc?ref=v1.0.0"
}

When authoring stacks in a catalog, you can use the update_source_with_cas attribute to allow relative paths in source attributes. This removes the need to plumb remote Git URLs through values expressions.

# stacks/my-stack/terragrunt.stack.hcl (in your catalog repository)
unit "service" {
source = "../..//units/my-service"
update_source_with_cas = true
path = "service"
}

The referenced unit can also use relative paths:

# units/my-service/terragrunt.hcl (in your catalog repository)
terraform {
source = "../..//modules/my-module"
update_source_with_cas = true
}

During stack generation, Terragrunt rewrites these relative sources to cas:: references that point to content stored in the CAS. The repository is cloned once, and subsequent stack generations resolve content from the local store without network access. Generated .terragrunt-stack files contain deterministic CAS references instead of version variables, so they do not produce diffs on regeneration.

The catalog source can be either a remote Git URL or a local filesystem path (absolute, or relative to the current working directory). Local sources are copied into a temporary directory before rewriting, so the original catalog directory is never modified. This makes the same catalog layout usable against a published Git ref or a local checkout, which is useful when iterating on a catalog before tagging a release.

For more details on using this with stacks, see Explicit Stacks: CAS Integration.

When Terragrunt clones a repository while using the CAS, if the repository is not found in the CAS, Terragrunt will clone the repository from the original URL and store it in the CAS for future use.

When generating a repository from the CAS, Terragrunt will hard link entries from the CAS to the new repository. This allows Terragrunt to deduplicate content across multiple repositories.

In the event that hard linking fails due to some operating system / host incompatibility with hard links, Terragrunt will fall back to performing copies of the content from the CAS.

The CAS is stored in the ~/.cache/terragrunt/cas directory. This directory can be safely deleted at any time, as Terragrunt will automatically regenerate the CAS as needed.

Avoid partial deletions of the CAS directory without care, as that might result in partially cloned repositories and unexpected behavior.

Terragrunt’s CAS uses a content-addressable storage model to deduplicate repository content from Git clones to save disk space and improve performance. Each Git object is identified by its hash, allowing identical content to be shared across multiple cloned repositories and repeated clones.

CAS uses Git’s native content addressing scheme where each object is uniquely identified by its hash. Terragrunt detects the hash algorithm used by the repository (sha1 or sha256) via git rev-parse --show-object-format. This means:

  • Identical content across different repositories shares the same hash
  • Same commit hash always represents the same content
  • Storage is partitioned by the first two characters of the hash (e.g., ab/abc123...)
  • Both SHA-1 and SHA-256 repositories are supported

The CAS store is organized into namespaced directories:

  • Directory~/.cache/terragrunt/cas/store/
    • Directoryblobs/ (file content from Git repositories and synthetic sources)
      • Directoryab/
        • abc123…xyz
        • abc123…xyz.lock
      • Directorycd/
        • cd7890…xyz
    • Directorytrees/ (Git-derived tree structures)
      • Directoryf3/
        • f39ea0…xyz
    • Directorysynth/
      • Directorytrees/ (synthetic trees created during CAS-backed stack generation)
        • Directoryde/
          • def456…xyz

The blobs/ directory stores all file content, identified by hash. Blobs are purely content-addressed, so the same file content always maps to the same hash regardless of origin. The trees/ directory stores Git-derived tree structures that describe the layout of files in a repository. The synth/trees/ directory stores synthetic tree structures created during CAS-backed stack generation when update_source_with_cas is used. These synthetic trees use a deterministic hash based on the Git reference and path within the repository.

Each content object within a namespace is stored at {hash[:2]}/{hash}, where the first two characters create a partition directory to avoid degraded file system performance from large flat directories.

When Terragrunt needs to clone a repository using the CAS it does the following, depending on whether the content is already in the CAS or not:

For cold clones, where the content is not already in the CAS:

  1. Terragrunt resolves the Git reference (branch/tag) to a commit hash
  2. The tree related to the commit hash is not found in the CAS
  3. Terragrunt clones the repository to a temporary directory
  4. All blobs and trees required to reproduce the repository are extracted
  5. Content is stored in the CAS, partitioned by hash prefix
  6. The tree structure is read from the CAS and hard links are created to the target directory

For warm clones, where the content is already in the CAS:

  1. Terragrunt resolves the Git reference to a commit hash
  2. CAS checks if the content exists
  3. The tree structure is read directly from the CAS
  4. Hard links are created from CAS to the target directory
Diagram

CAS achieves deduplication through hard links, which allows multiple files to use the same physical space on disk, avoiding duplicated content in repositories cloned by Terragrunt.

  • Hard Links: When the same content is requested multiple times, CAS creates hard links from the read-only store to each target directory
  • Automatic Fallback: If hard linking fails (e.g., cross-filesystem boundaries, operating system limitations), CAS automatically falls back to copying the content instead

CAS provides significant performance improvements:

  • Faster Subsequent Clones: Once content is in CAS, subsequent clones skip the network download and Git clone operations entirely
  • Reduced Disk Usage: Hard links share the same inode, so duplicate content only consumes disk space once, regardless of how many times the file is used in clones by Terragrunt