I’ve been tasked with generating Go structs from Terraform variables.tf files.
Generating primitive types (string, bool, number) is simple enough but complex types such as maps that wrap objects that wrap lists etc could be a bit of a rabbit hole to code.
I was wondering if anyone knows of an existing tool that generates Golang structs from variables.tf files?
Hi! Any luck with this ? I have the same requirement. Simple variable types like string, map, list etc is easy, but can’t figure out how to handle all allowed types- map(string) list(number) etc.
I don’t know of any existing tool which does this, but it’s also possible that I just don’t know what to look for because I’m not sure why it would be useful to generate Go code based on Terraform code.
If you can say a little more about why it would be useful to do that, I or someone else in the forum might be able to suggest a different way to meet the same goal, or at least have some more keywords to search for while looking for an existing solution.
In case you’d like to implement it yourself, I think you’d need to implement some code equivalent to how Terraform parses its type constraint syntax, by reviewing the type constraints documentation and writing code that can parse all of the different syntax forms it describes.
Since Terraform has a different type system than Go, you’ll need to devise a suitable mapping from the Terraform type system to the Go type system. Some particular questions you’ll need to decide answers to are:
- How will you represent the difference between nullable and non-nullable variables in Go? Go does not have the general idea of “nullable values” in the same way that Terraform does, so you’ll need to find an approximation.
- How will you represent the
any
placeholder that Terraform uses for automatic type inference? A type constraint which uses the any
keyword could be inferred as any Terraform language type at runtime.
- Do you need to take into account the idea of “optional attributes” on object types that is coming in the forthcoming Terraform v1.3 release? If so, does your system need to be aware of default values, or would it be sufficient to treat an optional attribute as just another “nullable” type?
- How will you represent Terraform’s tuple type kind? There isn’t really any directly-comparable type in the Go type system; Go’s only “structural” type kind is
struct
, which most directly corresponds with Terraform’s object type kind.
- How you will you represent numbers? Terraform has a single type
number
which most closely corresponds to the big.Float
type from Go’s math/big
package. However, that’s not very convenient to use so I expect you’d want to be able to use the more “normal” integer and float types. Terraform doesn’t distinguish between different-sized integers and different precisions of float, so you’d need to use some sort of heuristic to infer which of Go’s numeric types is the best fit for each specific instance of number
.
I expect there are other challenges I’m not thinking about, too. Hopefully there is some other way to solve whatever your underlying problem is, without introducing the hard problem of unambigously mapping between incompatible type systems.
1 Like
Hi, it’s a bit late for a reply but here is my following use case:
A Terraform repository that contains all the .tfvars file that are stored in the Git repository.
It roughly follows the Automate Terraform with GitHub Actions guide.
In this repository, users can contribute and that’s fine.
Now, we have some automation tool that listen to specific events to submit pull request to that repository. These tools create or update the tfvars files.
We want these tools to use Go struct derived from the defined variables schema (which can be objects, maps, etc.) to have a seamless integration between the repository input variables and our tools managing it.
Currently, nothing is generated and we maintain these structs by hand, which is a bit tedious. We’d prefer that to be generated in a single source.
I tried using GitHub - HewlettPackard/terraschema: Generate JSON Schema files based on a Terraform configuration to generate JSON Schema, to then generate Goland struct from a JSON Schema but is not satisfying to use.
Now, how would you automate tfvars creation/update by a tool against a Terraform repository ? Would you do the same thing as we’re doing ?