Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add global caching directory for modules supporting multiple versions #3611

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions cli/commands/hclfmt/action.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// `hclFmt` command recursively looks for hcl files in the directory tree starting at workingDir, and formats them
// based on the language style guides provided by Hashicorp. This is done using the official hcl2 library.

package hclfmt

import (
Expand Down Expand Up @@ -71,6 +68,10 @@ func Run(opts *options.TerragruntOptions) error {
skipFile = true
}

if util.ListContainsElement(pathList, "terragrunt-cache") {
skipFile = true
}

for _, excludeDir := range opts.HclExclude {
if util.ListContainsElement(pathList, excludeDir) {
skipFile = true
Expand Down
4 changes: 3 additions & 1 deletion cli/commands/terraform/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (

"github.com/gruntwork-io/terragrunt/cli/commands/terraform/creds"
"github.com/gruntwork-io/terragrunt/cli/commands/terraform/creds/providers/amazonsts"
"github.com/gruntwork-io/terragrunt/cli/commands/terraform/creds/providers/externalcmd"
"github.com/gruntwork-io/terragrunt/telemetry"

"github.com/gruntwork-io/terragrunt/terraform"
Expand Down Expand Up @@ -73,6 +72,9 @@ const TerraformExtensionGlob = "*.tf"
// code while another hook (e.g. `tflint`) is running. We use sync.Map to ensure atomic updates during concurrent access.
var sourceChangeLocks = sync.Map{}

// Global cache directory for modules
var globalCacheDir = filepath.Join(os.TempDir(), "terragrunt-cache")

// Run downloads terraform source if necessary, then runs terraform with the given options and CLI args.
// This will forward all the args and extra_arguments directly to Terraform.
func Run(ctx context.Context, opts *options.TerragruntOptions) error {
Expand Down
6 changes: 6 additions & 0 deletions cli/provider_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ func InitProviderCacheServer(opts *options.TerragruntOptions) (*ProviderCache, e
return nil, err
}

// Check if global cache directory is set
globalCacheDir := os.Getenv("TERRAGRUNT_GLOBAL_CACHE")
if globalCacheDir != "" {
opts.ProviderCacheDir = globalCacheDir
}

providerService := services.NewProviderService(opts.ProviderCacheDir, userProviderDir, cliCfg.CredentialsSource(), opts.Logger)

var (
Expand Down
53 changes: 53 additions & 0 deletions config/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package config_test

import (
"context"
"os"
"path/filepath"
"runtime"
"testing"

"github.com/gruntwork-io/terragrunt/config"
Expand Down Expand Up @@ -46,3 +49,53 @@ func TestTerragruntConfigCacheOperation(t *testing.T) {
assert.NotEmpty(t, actualResult)
assert.Equal(t, stubTerragruntConfig, actualResult)
}

func TestGlobalCacheDirectory(t *testing.T) {
t.Parallel()

// Set up global cache directory
globalCacheDir := filepath.Join(os.TempDir(), "terragrunt-global-cache")
err := os.MkdirAll(globalCacheDir, os.ModePerm)
assert.NoError(t, err)
defer os.RemoveAll(globalCacheDir)

// Set environment variable for global cache
os.Setenv("TERRAGRUNT_GLOBAL_CACHE", globalCacheDir)
defer os.Unsetenv("TERRAGRUNT_GLOBAL_CACHE")

// Create a new cache instance
cache := cache.NewCache[config.TerragruntConfig](testCacheName)

// Verify that the cache directory is set correctly
assert.Equal(t, globalCacheDir, os.Getenv("TERRAGRUNT_GLOBAL_CACHE"))
}

func TestGlobalCacheDirectoryMultipleOS(t *testing.T) {
t.Parallel()

// Set up global cache directory
globalCacheDir := filepath.Join(os.TempDir(), "terragrunt-global-cache")
err := os.MkdirAll(globalCacheDir, os.ModePerm)
assert.NoError(t, err)
defer os.RemoveAll(globalCacheDir)

// Set environment variable for global cache
os.Setenv("TERRAGRUNT_GLOBAL_CACHE", globalCacheDir)
defer os.Unsetenv("TERRAGRUNT_GLOBAL_CACHE")

// Create a new cache instance
cache := cache.NewCache[config.TerragruntConfig](testCacheName)

// Verify that the cache directory is set correctly
assert.Equal(t, globalCacheDir, os.Getenv("TERRAGRUNT_GLOBAL_CACHE"))

// Check for different operating systems
switch runtime.GOOS {
case "windows":
assert.Contains(t, globalCacheDir, `\`)
case "linux", "darwin":
assert.Contains(t, globalCacheDir, `/`)
default:
t.Fatalf("Unsupported OS: %s", runtime.GOOS)
}
}
19 changes: 19 additions & 0 deletions docs/_docs/02_features/caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,22 @@ find . -type d -name ".terragrunt-cache" -prune -exec rm -rf {} \;
```

Also consider setting the `TERRAGRUNT_DOWNLOAD` environment variable if you wish to place the cache directories somewhere else.

## Global Caching Directory

Terragrunt now supports a global caching directory for modules supporting different versions. This feature helps save space and improve performance by avoiding multiple caches for the same module and version.

### Benefits of Global Caching Directory

- **Space Efficiency**: By storing modules supporting different versions in a global caching directory, you can avoid redundant copies of the same module, saving disk space.
- **Performance Improvement**: With a global caching directory, Terragrunt can quickly access cached modules, reducing the time required to download and set up modules.

### Setting Up Global Caching Directory

To enable the global caching directory feature, you need to set the `TERRAGRUNT_GLOBAL_CACHE` environment variable to the desired path for the global cache directory. For example:

```bash
export TERRAGRUNT_GLOBAL_CACHE=/path/to/global/cache
```

Once set, Terragrunt will use the specified global caching directory for storing modules supporting different versions.