From 1e31c671c28ea05edcaecd88b79ddf1001c3ccab Mon Sep 17 00:00:00 2001 From: kmoe <5575356+kmoe@users.noreply.github.com> Date: Wed, 31 May 2023 20:25:15 +0100 Subject: [PATCH] terraform: expanded resources cannot genconfig (#33293) This temporary measure prevents a panic further down the line when there is an unmatched expanded resource instance import target when running in config gen mode. --- internal/terraform/context_plan2_test.go | 41 ++++++++++++++++++++++++ internal/terraform/transform_config.go | 7 ++++ 2 files changed, 48 insertions(+) diff --git a/internal/terraform/context_plan2_test.go b/internal/terraform/context_plan2_test.go index 27de456a8e..59b22069cb 100644 --- a/internal/terraform/context_plan2_test.go +++ b/internal/terraform/context_plan2_test.go @@ -4784,6 +4784,47 @@ import { }) } +func TestContext2Plan_importResourceConfigGenExpandedResource(t *testing.T) { + m := testModuleInline(t, map[string]string{ + "main.tf": ` +import { + to = test_object.a[0] + id = "123" +} +`, + }) + + p := simpleMockProvider() + ctx := testContext2(t, &ContextOpts{ + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("test"): testProviderFuncFixed(p), + }, + }) + p.ReadResourceResponse = &providers.ReadResourceResponse{ + NewState: cty.ObjectVal(map[string]cty.Value{ + "test_string": cty.StringVal("foo"), + }), + } + p.ImportResourceStateResponse = &providers.ImportResourceStateResponse{ + ImportedResources: []providers.ImportedResource{ + { + TypeName: "test_object", + State: cty.ObjectVal(map[string]cty.Value{ + "test_string": cty.StringVal("foo"), + }), + }, + }, + } + + _, diags := ctx.Plan(m, states.NewState(), &PlanOpts{ + Mode: plans.NormalMode, + GenerateConfigPath: "generated.tf", + }) + if !diags.HasErrors() { + t.Fatalf("expected plan to error, but it did not") + } +} + // config generation still succeeds even when planning fails func TestContext2Plan_importResourceConfigGenWithError(t *testing.T) { addr := mustResourceInstanceAddr("test_object.a") diff --git a/internal/terraform/transform_config.go b/internal/terraform/transform_config.go index 3275073be8..7d9aadb194 100644 --- a/internal/terraform/transform_config.go +++ b/internal/terraform/transform_config.go @@ -4,6 +4,7 @@ package terraform import ( + "fmt" "log" "github.com/hashicorp/terraform/internal/addrs" @@ -170,6 +171,12 @@ func (t *ConfigTransformer) transformSingle(g *Graph, config *configs.Config, ge // TODO: We could actually catch and process these kind of problems earlier, // this is something that could be done during the Validate process. for _, i := range importTargets { + // The case in which an unmatched import block targets an expanded + // resource instance can error here. Others can error later. + if i.Addr.Resource.Key != addrs.NoKey { + return fmt.Errorf("Config generation for count and for_each resources not supported.\n\nYour configuration contains an import block with a \"to\" address of %s. This resource instance does not exist in configuration.\n\nIf you intended to target a resource that exists in configuration, please double-check the address. Otherwise, please remove this import block or re-run the plan without the -generate-config-out flag to ignore the import block.", i.Addr) + } + abstract := &NodeAbstractResource{ Addr: i.Addr.ConfigResource(), importTargets: []*ImportTarget{i},