diff --git a/config/loader_hcl.go b/config/loader_hcl.go index 8e0d62c7ba..a40ad5ba77 100644 --- a/config/loader_hcl.go +++ b/config/loader_hcl.go @@ -209,6 +209,19 @@ func loadTerraformHcl(list *ast.ObjectList) (*Terraform, error) { // Get our one item item := list.Items[0] + // This block should have an empty top level ObjectItem. If there are keys + // here, it's likely because we have a flattened JSON object, and we can + // lift this into a nested ObjectList to decode properly. + if len(item.Keys) > 0 { + item = &ast.ObjectItem{ + Val: &ast.ObjectType{ + List: &ast.ObjectList{ + Items: []*ast.ObjectItem{item}, + }, + }, + } + } + // We need the item value as an ObjectList var listVal *ast.ObjectList if ot, ok := item.Val.(*ast.ObjectType); ok { diff --git a/config/loader_test.go b/config/loader_test.go index a23eba5287..ace70d90e4 100644 --- a/config/loader_test.go +++ b/config/loader_test.go @@ -384,6 +384,32 @@ backend (s3) } } +// test that the alternate, more obvious JSON format also decodes properly +func TestLoadFile_terraformBackendJSON2(t *testing.T) { + c, err := LoadFile(filepath.Join(fixtureDir, "terraform-backend-2.tf.json")) + if err != nil { + t.Fatalf("err: %s", err) + } + + if c == nil { + t.Fatal("config should not be nil") + } + + if c.Dir != "" { + t.Fatalf("bad: %#v", c.Dir) + } + + { + actual := terraformStr(c.Terraform) + expected := strings.TrimSpace(` +backend (s3) + foo`) + if actual != expected { + t.Fatalf("bad:\n%s", actual) + } + } +} + func TestLoadFile_terraformBackendMulti(t *testing.T) { _, err := LoadFile(filepath.Join(fixtureDir, "terraform-backend-multi.tf")) if err == nil { diff --git a/config/test-fixtures/terraform-backend-2.tf.json b/config/test-fixtures/terraform-backend-2.tf.json new file mode 100644 index 0000000000..d705fe85ae --- /dev/null +++ b/config/test-fixtures/terraform-backend-2.tf.json @@ -0,0 +1,9 @@ +{ + "terraform": { + "backend": { + "s3": { + "foo": "bar" + } + } + } +}