diff --git a/terraform/resource_address.go b/terraform/resource_address.go index 643833ff3..06e943f9e 100644 --- a/terraform/resource_address.go +++ b/terraform/resource_address.go @@ -119,7 +119,19 @@ func parseResourceAddressInternal(s string) (*ResourceAddress, error) { // Split based on ".". Every resource address should have at least two // elements (type and name). parts := strings.Split(s, ".") - if len(parts) < 2 || len(parts) > 3 { + if len(parts) < 2 || len(parts) > 4 { + return nil, fmt.Errorf("Invalid internal resource address format: %s", s) + } + + // Data resource if we have at least 3 parts and the first one is data + mode := config.ManagedResourceMode + if len(parts) > 2 && parts[0] == "data" { + mode = config.DataResourceMode + parts = parts[1:] + } + + // If we're not a data resource and we have more than 3, then it is an error + if len(parts) > 3 && mode != config.DataResourceMode { return nil, fmt.Errorf("Invalid internal resource address format: %s", s) } @@ -129,7 +141,7 @@ func parseResourceAddressInternal(s string) (*ResourceAddress, error) { Name: parts[1], Index: -1, InstanceType: TypePrimary, - Mode: config.ManagedResourceMode, + Mode: mode, } // If we have more parts, then we have an index. Parse that. diff --git a/terraform/resource_address_test.go b/terraform/resource_address_test.go index 02d9e82e5..2604441fe 100644 --- a/terraform/resource_address_test.go +++ b/terraform/resource_address_test.go @@ -36,14 +36,47 @@ func TestParseResourceAddressInternal(t *testing.T) { }, "aws_instance.foo[1]", }, + + "data resource": { + "data.aws_ami.foo", + &ResourceAddress{ + Mode: config.DataResourceMode, + Type: "aws_ami", + Name: "foo", + InstanceType: TypePrimary, + Index: -1, + }, + "data.aws_ami.foo", + }, + + "data resource with count": { + "data.aws_ami.foo.1", + &ResourceAddress{ + Mode: config.DataResourceMode, + Type: "aws_ami", + Name: "foo", + InstanceType: TypePrimary, + Index: 1, + }, + "data.aws_ami.foo[1]", + }, + + "non-data resource with 4 elements": { + "aws_instance.foo.bar.1", + nil, + "", + }, } for tn, tc := range cases { t.Run(tc.Input, func(t *testing.T) { out, err := parseResourceAddressInternal(tc.Input) - if err != nil { + if (err != nil) != (tc.Expected == nil) { t.Fatalf("%s: unexpected err: %#v", tn, err) } + if err != nil { + return + } if !reflect.DeepEqual(out, tc.Expected) { t.Fatalf("bad: %q\n\nexpected:\n%#v\n\ngot:\n%#v", tn, tc.Expected, out)