Skip to content

Commit

Permalink
fix: warn if Terragrunt dependency is outside project.
Browse files Browse the repository at this point in the history
Signed-off-by: i4k <[email protected]>
  • Loading branch information
i4ki committed Nov 29, 2024
1 parent 607852d commit 50aef54
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Given a version number `MAJOR.MINOR.PATCH`, we increment the:
### Fixed

- Fix the command-line parsing of `run` and `script run` which were not failing from unknown flags.
- Panic in the Terragrunt integration when the project had modules with dependency paths outside the current Terramate project.
- Now Terramate throw a warning for such configurations.

## v0.11.3

Expand Down
63 changes: 63 additions & 0 deletions e2etests/core/create_all_terragrunt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package core_test

import (
"path/filepath"
"regexp"
"testing"

. "github.com/terramate-io/terramate/e2etests/internal/runner"
Expand Down Expand Up @@ -358,6 +359,68 @@ func TestCreateAllTerragrunt(t *testing.T) {
StderrRegex: "Found a dependency cycle between modules",
},
},
{
name: "Terragrunt with dependency defined outside of the Terramate project",
layout: []string{
hclfile("terragrunt.hcl", Doc(
Block("terraform",
Str("source", "github.com/some/repo"),
),
Block("dependency",
Labels("module2"),
Str("config_path", `../other`),
),
Block("dependencies",
Expr("paths", `["../other"]`),
))),
hclfile("../other/terragrunt.hcl", Doc(
Block("terraform",
Str("source", "github.com/some/repo"),
),
)),
},
want: RunExpected{
StderrRegexes: []string{
regexp.QuoteMeta("Warning: Dependency outside of Terramate project detected in `dependency.config_path` configuration. Ignoring."),
regexp.QuoteMeta("Warning: Dependency outside of Terramate project detected in `dependencies.paths` configuration. Ignoring."),
},
Stdout: nljoin(
"Created stack /",
),
},
wantOrder: []string{"."},
},
{
name: "Terragrunt with dependency defined outside of the Terramate project (sharing same base path)",
layout: []string{
hclfile("terragrunt.hcl", Doc(
Block("terraform",
Str("source", "github.com/some/repo"),
),
Block("dependency",
Labels("module2"),
Str("config_path", `../sandboxy`),
),
Block("dependencies",
Expr("paths", `["../sandboxy"]`),
))),
hclfile("../sandboxy/terragrunt.hcl", Doc(
Block("terraform",
Str("source", "github.com/some/repo"),
),
)),
},
want: RunExpected{
StderrRegexes: []string{
regexp.QuoteMeta("Warning: Dependency outside of Terramate project detected in `dependency.config_path` configuration. Ignoring."),
regexp.QuoteMeta("Warning: Dependency outside of Terramate project detected in `dependencies.paths` configuration. Ignoring."),
},
Stdout: nljoin(
"Created stack /",
),
},
wantOrder: []string{"."},
},
} {
tc := tc
t.Run(tc.name, func(t *testing.T) {
Expand Down
8 changes: 7 additions & 1 deletion project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,14 @@ func PrjAbsPath(root, abspath string) Path {
if !filepath.IsAbs(abspath) {
panic(fmt.Errorf("path %q is not absolute", abspath))
}
if root == abspath {
return NewPath("/")
}
if !strings.HasSuffix(root, string(filepath.Separator)) { // accounts for root=/
root = root + string(filepath.Separator)
}
if !strings.HasPrefix(abspath, root) {
panic(fmt.Errorf("abspath %q does not start with root %q", abspath, root))
panic(fmt.Errorf(`abspath %q does not start with root %q`, abspath, root))
}
d := filepath.ToSlash(strings.TrimPrefix(abspath, root))
if d == "" {
Expand Down
30 changes: 24 additions & 6 deletions tg/tg_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ package tg

import (
"context"
"fmt"
"io"
"os"
"path"
"path/filepath"
"sort"
"strings"

"github.com/gruntwork-io/go-commons/env"
"github.com/gruntwork-io/terragrunt/config"
Expand All @@ -18,6 +19,7 @@ import (
"github.com/gruntwork-io/terragrunt/util"
"github.com/rs/zerolog/log"
"github.com/terramate-io/terramate/errors"
"github.com/terramate-io/terramate/printer"
"github.com/terramate-io/terramate/project"
"github.com/zclconf/go-cty/cty/function"
)
Expand Down Expand Up @@ -180,6 +182,11 @@ func ScanModules(rootdir string, dir project.Path, trackDependencies bool) (Modu
if !filepath.IsAbs(depPath) {
depPath = filepath.Join(tgMod.Path, depPath)
}
if !strings.HasPrefix(depPath, rootdir+string(filepath.Separator)) {
warnDependencyOutsideProject(mod, depPath, "dependency.config_path")

continue
}
dependsOn[project.PrjAbsPath(rootdir, depPath)] = struct{}{}
}
}
Expand All @@ -192,13 +199,16 @@ func ScanModules(rootdir string, dir project.Path, trackDependencies bool) (Modu

if tgConfig.Dependencies != nil {
for _, dep := range tgConfig.Dependencies.Paths {
var p project.Path
if !path.IsAbs(dep) {
p = mod.Path.Join(dep)
} else {
logger.Debug().Str("dep-path", dep).Msg("ignore absolute path")
if !filepath.IsAbs(dep) {
dep = filepath.Join(tgMod.Path, dep)
}
if !strings.HasPrefix(dep, rootdir+string(filepath.Separator)) {
warnDependencyOutsideProject(mod, dep, "dependencies.paths")

continue
}

p := project.PrjAbsPath(rootdir, dep)
mod.After = append(mod.After, p)
}
mod.After.Sort()
Expand Down Expand Up @@ -252,3 +262,11 @@ func newTerragruntOptions(dir string) *options.TerragruntOptions {

return opts
}

func warnDependencyOutsideProject(mod *Module, dep string, field string) {
printer.Stderr.WarnWithDetails(fmt.Sprintf("Dependency outside of Terramate project detected in `%s` configuration. Ignoring.", field),
errors.E("The Terragrunt module %s depends on the module at %s, which is located outside of the your current"+
" Terramate project. To resolve this ensure the dependent module is part of your Terramate project.",
mod.Path, dep),
)
}

0 comments on commit 50aef54

Please sign in to comment.