2

I now tried, everything but cant get this simple thing to work.

I got the following test_file.hcl:

variable "value" {
  test = "ok"
}

I want to parse it using the following code:

package hcl

import (
    "github.com/hashicorp/hcl/v2/hclsimple"
)

type Config struct {
    Variable string `hcl:"test"`
}


func HclToStruct(path string) (*Config, error) {
    var config Config

    return &config, hclsimple.DecodeFile(path, nil, &config)
 

But I receive:

test_file.hcl:1,1-1: Missing required argument; The argument "test" is required, but no definition was found., and 1 other diagnostic(s)

I checked with other projects using the same library but I cannot find my mistake .. I just dont know anymore. Can someone guide me into the right direction?

JMAD2016
  • 111
  • 1
  • 2
  • 9
  • The following diagnostics are returned: `&hcl.Diagnostic{Severity:1, Summary:"Missing required argument", Detail:"The argument \"test\" is required, but no definition was found.", Subject:(*hcl.Range)(0xc0000719c0), Context:(*hcl.Range)(nil), Expression:hcl.Expression(nil), EvalContext:(*hcl.EvalContext)(nil)} &hcl.Diagnostic{Severity:1, Summary:"Unsupported block type", Detail:"Blocks of type \"variable\" are not expected here.", Subject:(*hcl.Range)(0xc0000745d0), Context:(*hcl.Range)(nil), Expression:hcl.Expression(nil), EvalContext:(*hcl.EvalContext)(nil)} ` – Matteo Mar 03 '21 at 17:01

2 Answers2

3

The Go struct type you wrote here doesn't correspond with the shape of the file you want to parse. Notice that the input file has a variable block with a test argument inside it, but the Go type you wrote has only the test argument. For that reason, the HCL parser is expecting to find a file with just the test argument at the top-level, like this:

test = "ok"

To parse this Terraform-like structure with hclsimple will require you to write two struct types: one to represent the top level body containing variable blocks and another to represent the content of each of the blocks. For example:

type Config struct {
  Variables []*Variable `hcl:"variable,block"`
}

type Variable struct {
  Test *string `hcl:"test"`
}

With that said, I'll note that the Terraform language uses some features of HCL that hclsimple can't support, or at least can't support with direct decoding like this. For example, the type argument inside variable blocks is a special sort of expression called a type constraint which hclsimple doesn't support directly, and so parsing it will require using the lower-level HCL API. (That's what Terraform is doing internally.)

Martin Atkins
  • 62,420
  • 8
  • 120
  • 138
1

Thanks to @Martin Atkins, I now have the following code that works:

type Config struct {
    Variable []Variable `hcl:"variable,block"`
}

type Variable struct {
    Value string `hcl:"name,label"`
    Test string  `hcl:"test"`
}

With that I can parse a variables.tf like:

variable "projectname" {
  default = "cicd-template"
}

variable "ansibleuser" {
  default = "centos"
} 
JMAD2016
  • 111
  • 1
  • 2
  • 9