diff --git a/terraform/resource_address.go b/terraform/resource_address.go index a096c2706..06fbced8d 100644 --- a/terraform/resource_address.go +++ b/terraform/resource_address.go @@ -98,6 +98,16 @@ func (r *ResourceAddress) HasResourceSpec() bool { return r.Type != "" && r.Name != "" } +// WholeModuleAddress returns the resource address that refers to all +// resources in the same module as the receiver address. +func (r *ResourceAddress) WholeModuleAddress() *ResourceAddress { + return &ResourceAddress{ + Path: r.Path, + Index: -1, + InstanceTypeSet: false, + } +} + // stateId returns the ID that this resource should be entered with // in the state. This is also used for diffs. In the future, we'd like to // move away from this string field so I don't export this. diff --git a/terraform/resource_address_test.go b/terraform/resource_address_test.go index 3282b5289..bcf871c5e 100644 --- a/terraform/resource_address_test.go +++ b/terraform/resource_address_test.go @@ -685,3 +685,61 @@ func TestResourceAddressHasResourceSpec(t *testing.T) { }) } } + +func TestResourceAddressWholeModuleAddress(t *testing.T) { + cases := []struct { + Input string + Want string + }{ + { + "module.foo", + "module.foo", + }, + { + "module.foo.module.bar", + "module.foo.module.bar", + }, + { + "null_resource.baz", + "", + }, + { + "null_resource.baz[0]", + "", + }, + { + "data.null_data_source.baz", + "", + }, + { + "data.null_data_source.baz[0]", + "", + }, + { + "module.foo.null_resource.baz", + "module.foo", + }, + { + "module.foo.data.null_data_source.baz", + "module.foo", + }, + { + "module.foo.module.bar.null_resource.baz", + "module.foo.module.bar", + }, + } + + for _, test := range cases { + t.Run(test.Input, func(t *testing.T) { + addr, err := ParseResourceAddress(test.Input) + if err != nil { + t.Fatalf("error parsing address: %s", err) + } + gotAddr := addr.WholeModuleAddress() + got := gotAddr.String() + if got != test.Want { + t.Fatalf("%q: wrong result %#v; want %#v", test.Input, got, test.Want) + } + }) + } +}