terragrunt-atlantis-config icon indicating copy to clipboard operation
terragrunt-atlantis-config copied to clipboard

Circular dependencies detection

Open the-nando opened this issue 3 years ago • 1 comments

Thanks for the great tool! :)

I run into an issue when, given two Terragrunt files depending on each other and a common include:

test
├── bar
│   └── terragrunt.hcl
├── foo
│   └── terragrunt.hcl
└── terragrunt.hcl

test/terragrunt.hcl

generate "provider" {
  path      = "google_provider.tf"
  if_exists = "overwrite"
  contents  = <<EOF
__placeholder__
EOF
}

test/bar/terragrunt.hcl

include {
  path = find_in_parent_folders()
}

dependencies {
  paths = ["../foo"]
}

test/foo/terragrunt.hcl

include {
  path = find_in_parent_folders()
}

dependencies {
  paths = ["../bar"]
}

If I run terragrunt-atlantis-config generate --root test the command goes silent and hangs in a deadlock.

The deadlock I believe is caused by the duplicate function call suppression mechanism for getDependencies: when the second call to singleflight's Do comes with the same signature (path), the first one hasn't completed yet and never will because of the circular dependency, and the call hangs waiting indefinitely.

// Parses the terragrunt config at `path` to find all modules it depends on
func getDependencies(path string, terragruntOptions *options.TerragruntOptions) ([]string, error) {
	res, err, _ := requestGroup.Do(path, func() (interface{}, error) {

It would be great to have deadlock detection and log a message to the user in such a situation. Even better would be detecting the circular dependency and alert on that. For reference, Terragrunt implemented cycles detection with DFS here.

the-nando avatar Jan 06 '22 12:01 the-nando

This is a great callout, and would definitely be a welcome feature to add.

dmattia avatar Jan 06 '22 15:01 dmattia