diff --git a/config/loader_hcl.go b/config/loader_hcl.go index 8c81156e4..2988db19f 100644 --- a/config/loader_hcl.go +++ b/config/loader_hcl.go @@ -555,6 +555,37 @@ func loadManagedResourcesHcl(list *ast.ObjectList) ([]*Resource, error) { item.Pos()) } + // HCL special case: if we're parsing JSON then directly nested + // items will show up as additional "keys". We need to unwrap them + // since we expect only two keys. Example: + // + // { "foo": { "bar": { "baz": {} } } } + // + // Will show up with Keys being: []string{"foo", "bar", "baz"} + // when we really just want the first two. To fix this we unwrap + // them into the right value. + if len(item.Keys) > 2 && item.Keys[0].Token.JSON { + for len(item.Keys) > 2 { + // Pop off the last key + n := len(item.Keys) + key := item.Keys[n-1] + item.Keys[n-1] = nil + item.Keys = item.Keys[:n-1] + + // Wrap our value in a list + item.Val = &ast.ObjectType{ + List: &ast.ObjectList{ + Items: []*ast.ObjectItem{ + &ast.ObjectItem{ + Keys: []*ast.ObjectKey{key}, + Val: item.Val, + }, + }, + }, + } + } + } + if len(item.Keys) != 2 { return nil, fmt.Errorf( "position %s: resource must be followed by exactly two strings, a type and a name", diff --git a/config/loader_test.go b/config/loader_test.go index b7d53dee5..09b16f352 100644 --- a/config/loader_test.go +++ b/config/loader_test.go @@ -327,6 +327,22 @@ func TestLoadJSONBasic(t *testing.T) { } } +func TestLoadFileBasic_jsonNoName(t *testing.T) { + c, err := LoadFile(filepath.Join(fixtureDir, "resource-no-name.tf.json")) + if err != nil { + t.Fatalf("err: %s", err) + } + + if c == nil { + t.Fatal("config should not be nil") + } + + actual := resourcesStr(c.Resources) + if actual != strings.TrimSpace(basicJsonNoNameResourcesStr) { + t.Fatalf("bad:\n%s", actual) + } +} + func TestLoadFile_variables(t *testing.T) { c, err := LoadFile(filepath.Join(fixtureDir, "variables.tf")) if err != nil { @@ -837,6 +853,11 @@ foo bar ` +const basicJsonNoNameResourcesStr = ` +aws_security_group.allow_external_http_https (x1) + tags +` + const dirBasicOutputsStr = ` web_ip vars diff --git a/config/test-fixtures/resource-no-name.tf.json b/config/test-fixtures/resource-no-name.tf.json new file mode 100644 index 000000000..8dbf3e08c --- /dev/null +++ b/config/test-fixtures/resource-no-name.tf.json @@ -0,0 +1,11 @@ +{ + "resource" : { + "aws_security_group" : { + "allow_external_http_https" : { + "tags" : { + "Name" : "allow_external_http_https" + } + } + } + } +}