Skip to content

Commit df34fa8

Browse files
authored
Merge pull request hashicorp#10076 from hashicorp/f-depend-module
terraform: depends_on can reference entire modules
2 parents e3a01cc + 538302f commit df34fa8

18 files changed

Lines changed: 643 additions & 26 deletions

File tree

‎config/config.go‎

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -509,25 +509,8 @@ func (c *Config) Validate() error {
509509
}
510510
r.RawCount.init()
511511

512-
// Verify depends on points to resources that all exist
513-
for _, d := range r.DependsOn {
514-
// Check if we contain interpolations
515-
rc, err := NewRawConfig(map[string]interface{}{
516-
"value": d,
517-
})
518-
if err == nil && len(rc.Variables) > 0 {
519-
errs = append(errs, fmt.Errorf(
520-
"%s: depends on value cannot contain interpolations: %s",
521-
n, d))
522-
continue
523-
}
524-
525-
if _, ok := resources[d]; !ok {
526-
errs = append(errs, fmt.Errorf(
527-
"%s: resource depends on non-existent resource '%s'",
528-
n, d))
529-
}
530-
}
512+
// Validate DependsOn
513+
errs = append(errs, c.validateDependsOn(n, r.DependsOn, resources, modules)...)
531514

532515
// Verify provider points to a provider that is configured
533516
if r.Provider != "" {
@@ -802,6 +785,48 @@ func (c *Config) validateVarContextFn(
802785
}
803786
}
804787

788+
func (c *Config) validateDependsOn(
789+
n string,
790+
v []string,
791+
resources map[string]*Resource,
792+
modules map[string]*Module) []error {
793+
// Verify depends on points to resources that all exist
794+
var errs []error
795+
for _, d := range v {
796+
// Check if we contain interpolations
797+
rc, err := NewRawConfig(map[string]interface{}{
798+
"value": d,
799+
})
800+
if err == nil && len(rc.Variables) > 0 {
801+
errs = append(errs, fmt.Errorf(
802+
"%s: depends on value cannot contain interpolations: %s",
803+
n, d))
804+
continue
805+
}
806+
807+
// If it is a module, verify it is a module
808+
if strings.HasPrefix(d, "module.") {
809+
name := d[len("module."):]
810+
if _, ok := modules[name]; !ok {
811+
errs = append(errs, fmt.Errorf(
812+
"%s: resource depends on non-existent module '%s'",
813+
n, name))
814+
}
815+
816+
continue
817+
}
818+
819+
// Check resources
820+
if _, ok := resources[d]; !ok {
821+
errs = append(errs, fmt.Errorf(
822+
"%s: resource depends on non-existent resource '%s'",
823+
n, d))
824+
}
825+
}
826+
827+
return errs
828+
}
829+
805830
func (m *Module) mergerName() string {
806831
return m.Id()
807832
}

‎config/config_test.go‎

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package config
22

33
import (
44
"flag"
5+
"fmt"
56
"io/ioutil"
67
"log"
78
"os"
@@ -130,11 +131,55 @@ func TestConfig_emptyCollections(t *testing.T) {
130131
}
131132
}
132133

133-
func TestConfigValidate(t *testing.T) {
134-
c := testConfig(t, "validate-good")
135-
if err := c.Validate(); err != nil {
136-
t.Fatalf("err: %s", err)
134+
// This table test is the preferred way to test validation of configuration.
135+
// There are dozens of functions below which do not follow this that are
136+
// there mostly historically. They should be converted at some point.
137+
func TestConfigValidate_table(t *testing.T) {
138+
cases := []struct {
139+
Name string
140+
Fixture string
141+
Err bool
142+
ErrString string
143+
}{
144+
{
145+
"basic good",
146+
"validate-good",
147+
false,
148+
"",
149+
},
150+
151+
{
152+
"depends on module",
153+
"validate-depends-on-module",
154+
false,
155+
"",
156+
},
157+
158+
{
159+
"depends on non-existent module",
160+
"validate-depends-on-bad-module",
161+
true,
162+
"non-existent module 'foo'",
163+
},
164+
}
165+
166+
for i, tc := range cases {
167+
t.Run(fmt.Sprintf("%d-%s", i, tc.Name), func(t *testing.T) {
168+
c := testConfig(t, tc.Fixture)
169+
err := c.Validate()
170+
if (err != nil) != tc.Err {
171+
t.Fatalf("err: %s", err)
172+
}
173+
if err != nil {
174+
if tc.ErrString != "" && !strings.Contains(err.Error(), tc.ErrString) {
175+
t.Fatalf("expected err to contain: %s\n\ngot: %s", tc.ErrString, err)
176+
}
177+
178+
return
179+
}
180+
})
137181
}
182+
138183
}
139184

140185
func TestConfigValidate_badDependsOn(t *testing.T) {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module "child" {
2+
source = "./child"
3+
}
4+
5+
resource aws_instance "web" {
6+
depends_on = ["module.foo"]
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module "child" {
2+
source = "./child"
3+
}
4+
5+
resource aws_instance "web" {
6+
depends_on = ["module.child"]
7+
}

0 commit comments

Comments
 (0)