terraform: orphaned grandchild module inherits provider config
This fixes an issue where orphaned grandchild modules don't properly inherit their provider configurations from grandparents. I found this while working on shadow graphs (the shadow graph actually caught an inconsistency between runs and exposed this bug!), so I'm unsure if this affects any issue. To better explain the issue, I'll diagram things. Here is a hierarchy that _works_ (w/o this PR): ``` root |-- child1 (orphan) |-- child2 |-- grandchild ``` All modules in this case will successfully inherit provider configurations from "root". Here is a hierarchy that _doesn't work without this PR_: ``` root |-- child1 (orphan) |-- grandchild (orphan) ``` In this case, `child1` does successfully inherit the provider from root, but `grandchild` _will not_ unless `child1` had resources. If `child1` has no resources, it wouldn't inherit anything. This PR fixes that.
This commit is contained in:
parent
258005408b
commit
8c9097f454
|
@ -1390,6 +1390,54 @@ func TestContext2Apply_moduleOrphanProvider(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContext2Apply_moduleOrphanGrandchildProvider(t *testing.T) {
|
||||
m := testModule(t, "apply-module-orphan-provider-inherit")
|
||||
p := testProvider("aws")
|
||||
p.ApplyFn = testApplyFn
|
||||
p.DiffFn = testDiffFn
|
||||
|
||||
p.ConfigureFn = func(c *ResourceConfig) error {
|
||||
if _, ok := c.Get("value"); !ok {
|
||||
return fmt.Errorf("value is not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create a state with an orphan module that is nested (grandchild)
|
||||
state := &State{
|
||||
Modules: []*ModuleState{
|
||||
&ModuleState{
|
||||
Path: []string{"root", "parent", "child"},
|
||||
Resources: map[string]*ResourceState{
|
||||
"aws_instance.bar": &ResourceState{
|
||||
Type: "aws_instance",
|
||||
Primary: &InstanceState{
|
||||
ID: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Module: m,
|
||||
State: state,
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"aws": testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
if _, err := ctx.Plan(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if _, err := ctx.Apply(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Apply_moduleGrandchildProvider(t *testing.T) {
|
||||
m := testModule(t, "apply-module-grandchild-provider-inherit")
|
||||
p := testProvider("aws")
|
||||
|
|
|
@ -523,9 +523,10 @@ func (n *graphNodeProviderFlat) DependableName() []string {
|
|||
func (n *graphNodeProviderFlat) DependentOn() []string {
|
||||
var result []string
|
||||
|
||||
// If we're in a module, then depend on our parent's provider
|
||||
if len(n.PathValue) > 1 {
|
||||
prefix := modulePrefixStr(n.PathValue[:len(n.PathValue)-1])
|
||||
// If we're in a module, then depend on all parent providers. Some of
|
||||
// these may not exist, hence we depend on all of them.
|
||||
for i := len(n.PathValue); i > 1; i-- {
|
||||
prefix := modulePrefixStr(n.PathValue[:i-1])
|
||||
result = modulePrefixList(n.graphNodeProvider.DependableName(), prefix)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue