mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-25 10:40:02 +08:00
* Add `lib/tfgen` package for generating resource Terraform code
There are a number of different people working on features that will improve our
IaC (Infrastructure-as-Code) story. For example, the Machine & Workload Identity
team plan to build a set of wizards to enable the user to deploy `tbot` for
various CI/CD use-cases, the output of which will be a set of Terraform resources.
Our Terraform resource schemas are generated from protobuf definitions using the
`protoc-gen-terraform` plugin. As they can be arbitrarily complex (e.g. messages
inside lists inside messages inside maps etc.) using simple text templating can
be cumbersome and error-prone, and you need to carefully escape strings, etc.
This PR introduces a new package `lib/tfgen` which can generate Terraform code
programatically from resource structs (think `json.Marshal` but for Terraform
code).
Example usage:
role, err := types.NewRole("my-role", types.RoleSpecV6{/* ... */})
terraformCode, err := tfgen.Generate(role)
You can even inject comments on specific fields:
terraformCode, err := tfgen.Generate(
role,
tfgen.WithFieldComment("spec.allow", "Add your rules here..."),
)
For full examples of the output, see the golden files in `lib/tfgen/testdata`.
How it works:
It uses reflection - `protoreflect` for "modern" resources and Go's `reflect`
package for legacy/gogo-proto resources - to walk the message structure and
extract the fields into an intermediate representation.
Then it walks this intermediate representation and uses the Go HCL library to
emit Terraform code (ensuring proper escaping and formatting).
* Push protobuf type assertion up so we can constrain ReflectLegacy
* Clarify when to use ReflectModern or ReflectLegacy
* Handle embeded structs and other known difficult fields
14 lines
164 B
Plaintext
14 lines
164 B
Plaintext
resource "teleport_user" "bob" {
|
|
version = "v2"
|
|
|
|
metadata = {
|
|
name = "bob"
|
|
}
|
|
|
|
spec = {
|
|
traits = {
|
|
kubernetes_groups = ["viewers"]
|
|
}
|
|
}
|
|
}
|