diff --git a/config/config.go b/config/config.go index c055189a5..cdc2237c3 100644 --- a/config/config.go +++ b/config/config.go @@ -173,9 +173,27 @@ func (c *Config) Validate() error { } } + // Check that all references to modules are valid + modules := make(map[string]*Module) + dupped := make(map[string]struct{}) + for _, m := range c.Modules { + if _, ok := modules[m.Id()]; ok { + if _, ok := dupped[m.Id()]; !ok { + dupped[m.Id()] = struct{}{} + + errs = append(errs, fmt.Errorf( + "%s: module repeated multiple times", + m.Id())) + } + } + + modules[m.Id()] = m + } + dupped = nil + // Check that all references to resources are valid resources := make(map[string]*Resource) - dupped := make(map[string]struct{}) + dupped = make(map[string]struct{}) for _, r := range c.Resources { if _, ok := resources[r.Id()]; ok { if _, ok := dupped[r.Id()]; !ok { diff --git a/config/config_test.go b/config/config_test.go index 59242277b..581109e9c 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -44,6 +44,13 @@ func TestConfigValidate_countZero(t *testing.T) { } } +func TestConfigValidate_dupModule(t *testing.T) { + c := testConfig(t, "validate-dup-module") + if err := c.Validate(); err == nil { + t.Fatal("should not be valid") + } +} + func TestConfigValidate_dupResource(t *testing.T) { c := testConfig(t, "validate-dup-resource") if err := c.Validate(); err == nil { diff --git a/config/test-fixtures/validate-dup-module/main.tf b/config/test-fixtures/validate-dup-module/main.tf new file mode 100644 index 000000000..cf7fd3d9c --- /dev/null +++ b/config/test-fixtures/validate-dup-module/main.tf @@ -0,0 +1,7 @@ +module "aws_instance" "web" { + source = "foo" +} + +module "aws_instance" "web" { + source = "bar" +}