terrajen

package
v0.0.0-...-14f1a73 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 2, 2024 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package terrajen implements a Go code generator for terraform.

A Terraform Provider Schemas object is needed to generate code. This can be obtained using the [Terraform CLI]. We have a helper for creating a provider schemas object: github.com/golingon/lingon/pkg/terragen.GenerateProvidersSchema

This package leverages github.com/dave/jennifer for generating Go code.

[Terraform CLI]: https://developer.hashicorp.com/terraform/cli/commands/providers/schema

Example
package main

import (
	"bytes"
	"fmt"
	"log/slog"

	"github.com/golingon/lingon/pkg/internal/terrajen"
	tfjson "github.com/hashicorp/terraform-json"
	"github.com/zclconf/go-cty/cty"
)

var exampleProviderSchemas = tfjson.ProviderSchemas{
	Schemas: map[string]*tfjson.ProviderSchema{
		"registry.terraform.io/hashicorp/google": {
			// Schema for the provider configuration
			ConfigSchema: &tfjson.Schema{
				Block: &tfjson.SchemaBlock{
					Attributes: map[string]*tfjson.SchemaAttribute{
						"field": {
							AttributeType: cty.String,
							Required:      true,
						},
					},
				},
			},
			// Schema for the resource configurations
			ResourceSchemas: nil,
			// Schema for the data source configurations
			DataSourceSchemas: nil,
		},
	},
}

func main() {
	// First you need to obtain a Terraform Provider Schema, which can be done
	// using the
	// terragen package.
	// We will use some dummy data here
	ps := exampleProviderSchemas

	// Initialise the ProviderGenerator
	gen := terrajen.ProviderGenerator{
		// The module we are generating code into is called "mymodule" and the
		// directory to generate
		// code into is "gen".
		// This allows the generated code to refer to itself using this pkg path
		// as a prefix.
		GoProviderPkgPath: "mymodule/gen",
		// Filesystem location where to generate the files. This depends
		// entirely on *where* you
		// run the generator from
		GeneratedPackageLocation: "./gen",
		// Name of the provider
		ProviderName: "google",
		// Source of the provider
		ProviderSource: "hashicorp/google",
		// Version of the provider
		ProviderVersion: "4.58.0",
	}

	// For each of the provider, resources and data sources in the provider
	// schema, generate a
	// terrajen.Schema object using our ProviderGenerator
	prov := ps.Schemas["registry.terraform.io/hashicorp/google"]
	provSchema := gen.SchemaProvider(prov.ConfigSchema.Block)
	provFile := terrajen.ProviderFile(provSchema)
	// Typically we would save the file, e.g. provFile.Save("provider.go").
	// In this case we will write it to a buffer and print to stdout
	var pb bytes.Buffer
	if err := provFile.Render(&pb); err != nil {
		slog.Error("rendering provider file", err)
		return
	}
	fmt.Println(pb.String())

	// For each resource and data source (of which we have none), also do the
	// same. E.g.
	// for name, res := range prov.ResourceSchemas {}
	// for name, data := range prov.DataSourceSchemas {}

}
Output:

// CODE GENERATED BY github.com/golingon/lingon. DO NOT EDIT.

package google

import "github.com/golingon/lingon/pkg/terra"

var _ terra.Provider = (*Provider)(nil)

// Provider contains the configurations for provider.
type Provider struct {
	// Field: string, required
	Field terra.StringValue `hcl:"field,attr" validate:"required"`
}

// LocalName returns the provider local name for [Provider].
func (p *Provider) LocalName() string {
	return "google"
}

// Source returns the provider source for [Provider].
func (p *Provider) Source() string {
	return "hashicorp/google"
}

// Version returns the provider version for [Provider].
func (p *Provider) Version() string {
	return "4.58.0"
}

// Configuration returns the provider configuration for [Provider].
func (p *Provider) Configuration() interface{} {
	return p
}

Index

Examples

Constants

View Source
const HeaderComment = `CODE GENERATED BY github.com/golingon/lingon. DO NOT EDIT.`

Variables

This section is empty.

Functions

func DataSourceFile

func DataSourceFile(s *Schema) *jen.File

DataSourceFile generates a Go file for a Terraform data source configuration based on the given Schema

func JenDebug

func JenDebug(err error)

func ProviderFile

func ProviderFile(s *Schema) *jen.File

ProviderFile generates a Go file for a Terraform provider configuration based on the given Schema

func ResourceFile

func ResourceFile(s *Schema) *jen.File

ResourceFile generates a Go file for a Terraform resource configuration based on the given Schema

func SubPkgFile

func SubPkgFile(s *Schema) (*jen.File, bool)

SubPkgFile generates a Go file for the given schema. The schema should represent a sub-package or be the sub-types of a top-level provider/resource/data source.

For example, the AWS provider has a top-level provider config, with many nested subtypes. SubPkgFile would generate a file containing all the subtypes.

Types

type ProviderGenerator

type ProviderGenerator struct {
	// GoProviderPkgPath is the Go pkg path to the generated provider directory.
	// E.g. github.com/golingon/lingon/gen/aws
	GoProviderPkgPath string
	// GeneratedPackageLocation is the directory on the filesystem where the
	// generated Go files will be created.
	// The GoProviderPkgPath path must match the location of the generated files
	// so that they can be imported correctly.
	// E.g. if we are in a Go module called "my-module" and we generate the
	// files in a "gen" directory within the root of "my-module", then
	// GoProviderPkgPath is "my-module/gen" and the GeneratedPackageLocation is
	// "./gen" assuming we are running from the root of
	// "my-module"
	GeneratedPackageLocation string
	// ProviderName is the local name of the provider.
	// E.g. aws
	// https://developer.hashicorp.com/terraform/language/providers/requirements#local-names
	ProviderName string
	// ProviderSource is the source address of the provider.
	// E.g. registry.terraform.io/hashicorp/aws
	// https://developer.hashicorp.com/terraform/language/providers/requirements#source-addresses
	ProviderSource string
	// ProviderVersion is the version of thr provider.
	// E.g. 4.49.0
	ProviderVersion string
}

ProviderGenerator is created for each provider and is used to generate the schema for each resource and data object, and the provider configuration. The schemas are used by the generator to create the Go files and sub packages.

func (*ProviderGenerator) SchemaData

func (a *ProviderGenerator) SchemaData(
	name string,
	sb *tfjson.SchemaBlock,
) *Schema

SchemaData creates a schema for the given data object for the provider represented by ProviderGenerator

func (*ProviderGenerator) SchemaProvider

func (a *ProviderGenerator) SchemaProvider(sb *tfjson.SchemaBlock) *Schema

SchemaProvider creates a schema for the provider config block for the provider represented by ProviderGenerator

func (*ProviderGenerator) SchemaResource

func (a *ProviderGenerator) SchemaResource(
	name string,
	sb *tfjson.SchemaBlock,
) *Schema

SchemaResource creates a schema for the given resource for the provider represented by ProviderGenerator

type Schema

type Schema struct {
	SchemaType           SchemaType // resource / provider / data
	GoProviderPkgPath    string     // github.com/golingon/lingon/gen/providers
	GeneratedPkgLocation string     // gen/providers/aws
	ProviderName         string     // aws
	ProviderSource       string     // registry.terraform.io/hashicorp/aws
	ProviderVersion      string     // 4.49.0
	PackageName          string     // aws
	Type                 string     // aws_iam_role

	// Structs
	StructName           string // iam_role => IamRole
	ArgumentStructName   string // iam_role => IamRoleArgs
	AttributesStructName string // iam_role => iamRoleAttributes
	StateStructName      string // iam_role => iamRoleState

	Receiver string // iam_role => ir

	SubPkgName string // iam_role => iamrole
	// SubPkgPath is the filepath for the schema entities types (args,
	// attributes, state).
	SubPkgPath string
	FilePath   string // gen/providers/aws/ xxx
	// contains filtered or unexported fields
}

Schema is used to store all the relevant information required for the Go code generator. A schema can represent a resource, a data object or the provider configuration.

func (*Schema) SubPkgQualPath

func (s *Schema) SubPkgQualPath() string

type SchemaType

type SchemaType string
const (
	SchemaTypeProvider   SchemaType = "provider"
	SchemaTypeResource   SchemaType = "resource"
	SchemaTypeDataSource SchemaType = "data"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL