diff --git a/internal/lang/globalref/analyzer_meta_references.go b/internal/lang/globalref/analyzer_meta_references.go index b7c6db22e..4646b55e5 100644 --- a/internal/lang/globalref/analyzer_meta_references.go +++ b/internal/lang/globalref/analyzer_meta_references.go @@ -40,6 +40,8 @@ func (a *Analyzer) MetaReferences(ref Reference) []Reference { switch targetAddr := ref.LocalRef.Subject.(type) { case addrs.InputVariable: return a.metaReferencesInputVariable(moduleAddr, targetAddr, remaining) + case addrs.LocalValue: + return a.metaReferencesLocalValue(moduleAddr, targetAddr, remaining) case addrs.ModuleCallInstanceOutput: return a.metaReferencesOutputValue(moduleAddr, targetAddr, remaining) case addrs.ModuleCallInstance: @@ -136,6 +138,23 @@ func (a *Analyzer) metaReferencesOutputValue(callerAddr addrs.ModuleInstance, ad return absoluteRefs(calleeAddr, refs) } +func (a *Analyzer) metaReferencesLocalValue(moduleAddr addrs.ModuleInstance, addr addrs.LocalValue, remain hcl.Traversal) []Reference { + modCfg := a.ModuleConfig(moduleAddr) + if modCfg == nil { + return nil + } + + local := modCfg.Locals[addr.Name] + if local == nil { + return nil + } + + // We don't check for errors here because we'll make a best effort to + // analyze whatever partial result HCL is able to extract. + refs, _ := lang.ReferencesInExpr(local.Expr) + return absoluteRefs(moduleAddr, refs) +} + func (a *Analyzer) metaReferencesModuleCall(callerAddr addrs.ModuleInstance, addr addrs.ModuleCallInstance, remain hcl.Traversal) []Reference { calleeAddr := callerAddr.Child(addr.Call.Name, addr.Key) @@ -181,6 +200,7 @@ func (a *Analyzer) metaReferencesResourceInstance(moduleAddr addrs.ModuleInstanc if providerSchema == nil { return nil } + resourceTypeSchema, _ := providerSchema.SchemaForResourceAddr(addr.Resource) if resourceTypeSchema == nil { return nil diff --git a/internal/lang/globalref/analyzer_meta_references_test.go b/internal/lang/globalref/analyzer_meta_references_test.go index 340e8760f..c693890cf 100644 --- a/internal/lang/globalref/analyzer_meta_references_test.go +++ b/internal/lang/globalref/analyzer_meta_references_test.go @@ -19,6 +19,13 @@ func TestAnalyzerMetaReferences(t *testing.T) { `local.a`, nil, }, + { + ``, + `local.single`, + []string{ + "::test_thing.single.id", + }, + }, { ``, `test_thing.single`, diff --git a/internal/lang/globalref/testdata/assorted/assorted-root.tf b/internal/lang/globalref/testdata/assorted/assorted-root.tf index d61297232..09f730eee 100644 --- a/internal/lang/globalref/testdata/assorted/assorted-root.tf +++ b/internal/lang/globalref/testdata/assorted/assorted-root.tf @@ -1,7 +1,7 @@ - locals { a = "hello world" b = 2 + single = test_thing.single.id } resource "test_thing" "single" { diff --git a/internal/lang/globalref/testdata/contributing-resources/compute/contributing-resources-compute.tf b/internal/lang/globalref/testdata/contributing-resources/compute/contributing-resources-compute.tf index c83daffe8..a88ec466f 100644 --- a/internal/lang/globalref/testdata/contributing-resources/compute/contributing-resources-compute.tf +++ b/internal/lang/globalref/testdata/contributing-resources/compute/contributing-resources-compute.tf @@ -20,6 +20,8 @@ locals { } ] ]) + + controllers = test_thing.controller } resource "test_thing" "worker" { @@ -39,7 +41,7 @@ resource "test_thing" "load_balancer" { string = var.network.vpc_id dynamic "list" { - for_each = test_thing.controller + for_each = local.controllers content { z = list.value.string }