terraform icon indicating copy to clipboard operation
terraform copied to clipboard

Improve handling of (invalid) self-referenced module source

Open radeksimko opened this issue 3 years ago • 4 comments

Current Terraform Version

Terraform v1.2.6
on darwin_arm64

Background

Given an (invalid) config, such as the following:

module "example" {
  source = "./"
}

Terraform would produce somewhat unhelpful and verbose error message on terraform init

$ terraform init
terraform init output
Initializing modules...
- test in .
- test.test in .
- test.test.test in .
- test.test.test.test in .
- test.test.test.test.test in .
- test.test.test.test.test.test in .
- test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
- test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test in .
╷
│ Error: Failed to remove local module cache
│ 
│ Terraform tried to remove
│ .terraform/modules/test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test
│ in order to reinstall this module, but encountered an error: unlinkat
│ .terraform/modules/test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test:
│ file name too long
╵

╷
│ Error: Failed to remove local module cache
│ 
│ Terraform tried to remove
│ .terraform/modules/test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test
│ in order to reinstall this module, but encountered an error: unlinkat
│ .terraform/modules/test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test:
│ file name too long
╵

Terraform also persists the following into .terraform/modules/modules.json:

modules.json
{
    "Modules": [
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "",
            "Source": "",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        },
        {
            "Key": "test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test",
            "Source": "./.",
            "Dir": "."
        }
    ]
}

Note that similar error is also reproducible with multiple modules which eventually end up in cycle (by calling each other), so validating a module source in isolation (i.e. just checking for ./) may not be sufficient.

Use-cases

Give users more actionable and clearer feedback.

Proposal

Check whether the module source refers back to the same module and return a human-readable & actionable error early.

radeksimko avatar Aug 02 '22 13:08 radeksimko

Thanks for this. I think a similar issue may have been opened before, but I can't find it.

kmoe avatar Aug 02 '22 14:08 kmoe

!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!

must contain only letters, digits, and dashes, and may not use leading or trailing dashes goroutine 1 [running]: runtime/debug.Stack() /usr/local/go/src/runtime/debug/stack.go:24 +0x65 runtime/debug.PrintStack() /usr/local/go/src/runtime/debug/stack.go:16 +0x19 github.com/hashicorp/terraform/internal/logging.PanicHandler() /home/circleci/project/project/internal/logging/panic.go:55 +0x153 panic({0x2468940, 0xc00050d0c0}) /usr/local/go/src/runtime/panic.go:844 +0x258 github.com/hashicorp/terraform/internal/addrs.MustParseProviderPart({0xc0004ab150?, 0x0?}) /home/circleci/project/project/internal/addrs/provider.go:449 +0x4c github.com/hashicorp/terraform/internal/addrs.NewDefaultProvider(...) /home/circleci/project/project/internal/addrs/provider.go:122 github.com/hashicorp/terraform/internal/addrs.ImpliedProviderForUnqualifiedType({0xc0004ab150?, 0xc0004ab150?}) /home/circleci/project/project/internal/addrs/provider.go:114 +0x11b github.com/hashicorp/terraform/internal/configs.validateProviderConfigs.func1(0xc000630090?) /home/circleci/project/project/internal/configs/provider_validation.go:161 +0x145 github.com/hashicorp/terraform/internal/configs.validateProviderConfigs(0x0, 0xc000184b60, 0x0) /home/circleci/project/project/internal/configs/provider_validation.go:180 +0x14bd github.com/hashicorp/terraform/internal/configs.BuildConfig(0xc0000a0790, {0x2eae200, 0xc00050d020}) /home/circleci/project/project/internal/configs/config_build.go:34 +0xf0 github.com/hashicorp/terraform/internal/configs/configload.(*Loader).LoadConfig(0xc0005f8550, {0x29034ee?, 0x23?}) /home/circleci/project/project/internal/configs/configload/loader_load.go:33 +0xfd github.com/hashicorp/terraform/internal/command.(*Meta).loadConfig(0x0?, {0xc00087a270?, 0x0?}) /home/circleci/project/project/internal/command/meta_config.go:47 +0x98 github.com/hashicorp/terraform/internal/command.(*InitCommand).Run(0xc0001044e0, {0xc0000623f0, 0x0, 0x0}) /home/circleci/project/project/internal/command/init.go:207 +0x139d github.com/mitchellh/cli.(*CLI).Run(0xc0000a52c0) /home/circleci/go/pkg/mod/github.com/mitchellh/[email protected]/cli.go:262 +0x5f8 main.realMain() /home/circleci/project/project/main.go:312 +0x15d4 main.main() /home/circleci/project/project/main.go:58 +0x19

i created a file with .tf and run CMD terraform plan

after that i delete the file. again run the cmd it was through this error.

tthakre avatar Aug 04 '22 12:08 tthakre

machine is window Terraform v1.2.6 on windows_amd64

tthakre avatar Aug 04 '22 12:08 tthakre

@tthakre This is a helpful crash report, but it seems unrelated to the original report, so I created a separate issue to track it.

radeksimko avatar Aug 04 '22 12:08 radeksimko