Closed yorinasub17 closed 3 years ago
Really cool POC, Yori. Very forward thinking. I love the flexibility that you've brought and some of the capabilities that this unleashes! I don't have any comments on your implementation. Looks quite good to me overall.
Or Hashicorp keeps their promise of building a json->hcl converter so we can start using this for the architecture catalog!
This is the only thing that has my head spinning given that we are just now completing the architecture catalog using the Go templating engine. Is there enough benefits in jsonnet to merit refactoring all the templates again, when we just spent months perfecting it? But the JSON->HCL converter doesn't exist for now, so perhaps it's a moot point.
This is the only thing that has my head spinning given that we are just now completing the architecture catalog using the Go templating engine. Is there enough benefits in jsonnet to merit refactoring all the templates again, when we just spent months perfecting it? But the JSON->HCL converter doesn't exist for now, so perhaps it's a moot point.
Good question! I was thinking this would be an incremental shift. Given that this hasn't gone through the rounds of testing and production usage, I envision us being very careful when and where we introduce this if at all. I see us using this in places that require more complex templating logic (perhaps where we need to DRY things up, like with stringing through a service port across the stack from network firewalls to the container port), but rely on good old go templating for most things.
Perhaps at some point we have enough things in jsonnet, and we've tested it out enough to be confident in the technology that we start migrating implementations and thus eventually architecture catalog is solely in jsonnet, but this will take time.
But the home page says, "Generate JSON, YAML, INI, and other formats" and shows some helpers like std.manifestYamlDoc... So maybe we can do more than just output JSON?
These work because you can convert from JSON to these formats relatively easily. However, because each of these are supersets of JSON, there is data loss in the conversion (e.g., you can't render yaml comments).
The support for syntax highlighting is huge... But it seems like it doesn't really solve the problem we have. That is, if we're generating, say, pieces of HCL code, the JSON around it will be syntax highlighted, but the HCL itself—which is just as important to highlight—will be seen as an opaque string, right?
As mentioned in the drawbacks above, we can't really generate anything other than JSON. All the other formats depend on transpilers that take the rendered JSON and convert it to the respective formats. So generating HCL is actually about generating the JSON configuration version, and transpiling that output to HCL. In that regard, you don't really need HCL syntax highlighting.
But note that we can't really use this in the architecture catalog yet because there is no JSON to HCL transpiler. Hashicorp promised that this was coming in the tf12 announcement post, but it doesn't exist yet. With that said, I think it is worth experimenting jsonnet to see if there is any advantage to using it to render terragrunt configuration over go templating with our use case of preview environments.
As mentioned above in the PR description, I think json based terragrunt config is actually fine for preview environments because they are by nature not meant to be user manipulated. So I was thinking that we can take advantage of jsonnet there, and experiment to see if it improves the template writing experience.
As a side note, this is actually step 1 in a multiseries hackday project to convert the dogfood preview environments to ECS deploy runner. Here are the next steps:
Thanks for the reviews! I'm going to merge this in now so we have it available for further experimentation in the wild in the preview env use case.
This PR adds support for alternative templating engines besides Go Templating, starting with jsonnet. I chose jsonnet here instead of others like dhall for a few reasons:
jsonnet
is very popular in the Kubernetes space, with tools like kapitan providing first class support. This means there are nice libraries that one can use to generate kubernetes manifests using jsonnet.Unlike Go templating,
jsonnet
has first class editor support (e.g., https://github.com/google/vim-jsonnet).Unlike Go templating,
jsonnet
is ergonomic when it comes to local variables and functions.Unlike
dhall
,jsonnet
supports external data injection, which works really well with boilerplates mental model around template vars. See the documentation update for more details.dhall
is a very strictly typed language from the ML family (e.g., Ocaml, ReasonML, Haskell, etc). As such, it becomes very verbose to write even with Optionals, which is not well suited for something liketerragrunt.hcl
where many blocks and attributes are optional.Note that I omitted some features for hackday:
json
.boilerplate.yml
asboilerplate.jsonnet
and having boilerplate parse those). Again, not sure how much this is worth (although the ability to use imports and functions there would be awesome).Use case
The one big limitation of
jsonnet
is that it can only renderjson
data. This can be converted to other formats, but it must usejson
as an intermediary, which means lots of useful things can be lost (e.g., comments). This makes it hard to use with something like our architecture catalog.However, this is useful for templating out configurations that are not meant to be user parsed or user touched. The primary use case that motivated me to implement this is preview environments. I look at preview environments as machine generated infrastructure configuration that are not meant to be touched by the user. In these cases, it works quite well to use something like jsonnet to implement the templates, seeing as both
terraform
andterragrunt
supportjson
configuration. Furthermore,json
configuration withterragrunt
supports comments liketerraform
(using the special"//"
key).For example, at the bottom of the PR description is what the template for the aperture preview environment might look like. Some things to highlight:
#
) and rendered comments ("//"
attribute). Note that go templates also supports this, but personally it is easier to distinguish with jsonnet given the editor syntax highlighting that doesn't mix the two.I also can see us extending this further. For example, we can export a
libsonnet
file from terragrunt that is autogenerated from the config to type check the json usingassert
, which can allow us to give the user an error during rendering of the template if the resultingterragrunt.hcl.json
is malformed.Side note: Hopefully in the future we can even have static type checking from the editor while we write this (e.g., see https://github.com/google/jsonnet/issues/605). Or Hashicorp keeps their promise of building a json->hcl converter so we can start using this for the architecture catalog!