use the correct context when evaluating imports

pull/38352/head
Kristin Laemmert 1 month ago
parent 9d74c3014f
commit e085a3c180

@ -17,7 +17,7 @@ type ImportStatement struct {
// FindImportStatements recurses through the modules of the given configuration
// and returns a set of all "import" blocks defined within after deduplication
// on the From address.
// on the To address.
//
// An "import" block in a parent module overrides an import block in a child
// module when both target the same configuration object.

@ -4,11 +4,13 @@
package terraform
import (
"encoding/json"
"testing"
"github.com/zclconf/go-cty/cty"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/states"
@ -19,7 +21,12 @@ import (
func TestContextApply_import_in_module(t *testing.T) {
m := testModule(t, "import-block-in-module")
p := simpleMockProvider()
p := mockProviderWithResourceTypeSchema("test_object", &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Computed: true},
"test_string": {Type: cty.String, Optional: true},
},
})
p.ImportResourceStateFn = func(req providers.ImportResourceStateRequest) providers.ImportResourceStateResponse {
return providers.ImportResourceStateResponse{
ImportedResources: []providers.ImportedResource{
@ -27,15 +34,20 @@ func TestContextApply_import_in_module(t *testing.T) {
TypeName: "test_object",
State: cty.ObjectVal(map[string]cty.Value{
"test_string": cty.StringVal("importable"),
"id": cty.StringVal(req.ID),
}),
},
},
}
}
p.ReadResourceResponse = &providers.ReadResourceResponse{
NewState: cty.ObjectVal(map[string]cty.Value{
"test_string": cty.StringVal("importable"),
}),
p.ReadResourceFn = func(r providers.ReadResourceRequest) providers.ReadResourceResponse {
id := r.PriorState.GetAttr("id")
return providers.ReadResourceResponse{
NewState: cty.ObjectVal(map[string]cty.Value{
"test_string": cty.StringVal("importable"),
"id": id,
}),
}
}
ctx := testContext2(t, &ContextOpts{
@ -56,10 +68,30 @@ func TestContextApply_import_in_module(t *testing.T) {
t.Fatal("resource not imported")
}
rs := state.ResourceInstance(mustResourceInstanceAddr("module.child.test_object.bar"))
rs := state.ResourceInstance(mustResourceInstanceAddr("module.child.test_object.bar[\"first\"]"))
if rs == nil {
t.Fatal("imported resource not found in module")
}
var attrs map[string]interface{}
err := json.Unmarshal(rs.Current.AttrsJSON, &attrs)
if err != nil {
t.Fatal(err)
}
if got, want := attrs["id"], "testa"; got != want {
t.Fatalf("wrong id for \"first\" got: %#v\nwant: %#v", got, want)
}
rs = state.ResourceInstance(mustResourceInstanceAddr("module.child.test_object.bar[\"second\"]"))
if rs == nil {
t.Fatal("imported resource not found in module")
}
err = json.Unmarshal(rs.Current.AttrsJSON, &attrs)
if err != nil {
t.Fatal(err)
}
if got, want := attrs["id"], "testb"; got != want {
t.Fatalf("wrong id for \"second\" got: %#v\nwant: %#v", got, want)
}
}
func TestContextApply_import_in_nested_module(t *testing.T) { // more nested than the test above. nesteder.

@ -178,6 +178,9 @@ func (n *nodeExpandPlannableResource) expandResourceImports(ctx EvalContext, all
// do I need to get all possible expansions for the imp.RelModule and then only use the one for this actual node?
allMods := ctx.InstanceExpander().AllInstances().InstancesForModule(imp.RelModule, false)
for _, mod := range allMods {
// get the context from the module the import was defined in
ctx = evalContextForModuleInstance(ctx, mod)
state = ctx.State()
if imp.Config.ForEach == nil {
traversal, hds := hcl.AbsTraversalForExpr(imp.Config.To)
diags = diags.Append(hds)

@ -1,7 +1,16 @@
import {
to = test_object.bar
id = "importable"
locals {
ids = {
first = "testa"
second = "testb"
}
}
resource test_object bar {
for_each = local.ids
}
resource "test_object" "bar" {
import {
for_each = local.ids
to = test_object.bar[each.key]
id = each.value
}
Loading…
Cancel
Save