tofu

package
v3.5.0 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 31 Imported by: 0

Documentation

Overview

Package tofu — binary.go implements the OpenTofu binary manager.

Resolution order (three tiers), highest precedence first:

  1. Config override: if cli.Config.TofuBinaryPath is set, that path is used verbatim (after validating it exists and is executable). Nothing is downloaded or cached.
  2. Cache hit: if .gothicCli/bin/tofu already exists and is executable, it is returned without touching the network.
  3. Download: the pinned OpenTofu version is fetched via github.com/opentofu/tofudl, written to .gothicCli/bin/tofu, marked executable, and returned.

Package tofu wraps the OpenTofu binary, the Docker engine, and AWS SDK clients into a single deployment engine usable by cmd/deploy.go.

Index

Constants

View Source
const PinnedTofuVersion = "1.9.0"

PinnedTofuVersion is the single OpenTofu version this CLI downloads and runs. Never resolve "latest" at runtime — a pinned version keeps deploys reproducible and lets us vet the exact tofu behavior we ship against.

Variables

This section is empty.

Functions

func DeleteRemoteState

func DeleteRemoteState(ctx context.Context, region, profile, stateBucket, lockTable string) error

DeleteRemoteState empties and deletes the OpenTofu remote state bucket (including all object versions and delete markers) and deletes the DynamoDB lock table. It loads its own aws.Config from the given region + profile so it can be called from cmd/deploy.go without an engine instance.

func OtherStageStates

func OtherStageStates(ctx context.Context, region, profile, stateBucket, projectName, currentStage string) ([]string, error)

OtherStageStates returns the stages — other than currentStage — that still have an OpenTofu state file in the shared state bucket. State keys are laid out as "gothic/<project>/<stage>/terraform.tfstate" (see main.tf.json backend), so a delimited list of "gothic/<project>/" yields one common prefix per stage. It is used to refuse deleting the shared state backend while other stages depend on it (deleting it would orphan their resources). An absent bucket yields no stages.

func ResourceSuffix

func ResourceSuffix(goModName, projectName string) string

ResourceSuffix returns a deterministic 8-character hex suffix derived from the Go module name and project name. It replaces the random .gothicCli/app-id.txt mechanism used in v2: because it is computed from the (globally unique) module path, every developer on the project and every fresh `git clone` produces the same suffix, so AWS resource names stay stable without an init-time file.

Types

type BinaryManager

type BinaryManager interface {
	// EnsureBinary returns the absolute (or project-relative) path to a usable
	// tofu binary.
	EnsureBinary(ctx context.Context) (string, error)
}

BinaryManager resolves the OpenTofu binary, downloading and caching it under .gothicCli/bin/tofu when necessary.

func NewBinaryManager

func NewBinaryManager(c *cli.Config) BinaryManager

NewBinaryManager returns a BinaryManager that resolves the tofu binary using the config override → cache → download tiers documented at the package level.

type CDNEngine

type CDNEngine interface {
	// SyncAssets does a single-pass concurrent upload of localDir to bucketName.
	SyncAssets(ctx context.Context, bucketName string, localDir string) error

	// RemoveAssets deletes uploaded assets from bucketName.
	RemoveAssets(ctx context.Context, bucketName string) error

	// InvalidateCache creates a /* invalidation on the CDN distribution.
	InvalidateCache(ctx context.Context, distributionID string) error
}

CDNEngine is the provider-agnostic contract for syncing static assets to the origin bucket and invalidating the CDN cache. Concrete implementations (e.g. CloudFrontCDN) provide the behavior.

type CloudFrontCDN

type CloudFrontCDN struct {
	// contains filtered or unexported fields
}

CloudFrontCDN implements CDNEngine for AWS: it uploads static assets to the origin S3 bucket and invalidates the CloudFront distribution cache.

func NewCloudFrontCDN

func NewCloudFrontCDN(awsCfg aws.Config) *CloudFrontCDN

NewCloudFrontCDN constructs a CloudFrontCDN from a loaded aws.Config.

func (*CloudFrontCDN) InvalidateCache

func (c *CloudFrontCDN) InvalidateCache(ctx context.Context, distID string) error

InvalidateCache creates a /* invalidation on the given distribution. The caller reference is the current nanosecond timestamp so each call is unique.

func (*CloudFrontCDN) RemoveAssets

func (c *CloudFrontCDN) RemoveAssets(ctx context.Context, bucketName string) error

RemoveAssets deletes every object in bucketName, batching deletes into the 1000-object groups DeleteObjects accepts.

func (*CloudFrontCDN) SyncAssets

func (c *CloudFrontCDN) SyncAssets(ctx context.Context, bucketName, sourceDir string) error

SyncAssets uploads every file under sourceDir to bucketName, concurrently (bounded to syncUploadLimit). Content-Type is inferred from the extension; .wasm and .wasm.gz files are special-cased so CloudFront serves them with the correct type and (for .gz) Content-Encoding in a single PutObject pass.

type DeploymentEngine

type DeploymentEngine interface {
	// Prepare bootstraps state backend resources (S3 state bucket + DynamoDB
	// lock table) and generates the .tf.json working directory for the given
	// stage. Must be called before Build/Deploy/Destroy.
	Prepare(ctx context.Context, stage string) error

	// Build builds and pushes the container image; returns the image URI. The
	// repository name is the one computed in Prepare, so it is not passed here.
	Build(ctx context.Context, tag string) (imageURI string, err error)

	// Deploy runs tofu init + apply and returns the stack outputs.
	Deploy(ctx context.Context) (map[string]string, error)

	// Destroy runs tofu destroy.
	Destroy(ctx context.Context) error
}

DeploymentEngine is the provider-agnostic contract used by cmd/deploy.go to run a full deploy/destroy lifecycle. The concrete implementation (TofuAwsEngine) holds the resolved *cli.Config and aws.Config internally, so callers only pass the stage. All resource names are computed by the engine.

type TofuAwsEngine

type TofuAwsEngine struct {
	// contains filtered or unexported fields
}

TofuAwsEngine implements DeploymentEngine for AWS. It wires together the OpenTofu binary manager, the .tf.json generator, the Docker engine, and the terraform-exec runner (which is OpenTofu-compatible). All resource names are computed deterministically from the module name + project name via ResourceSuffix, so no per-machine state file is required.

func NewTofuAwsEngine

func NewTofuAwsEngine(c *cli.Config, awsCfg aws.Config) (*TofuAwsEngine, error)

NewTofuAwsEngine constructs a TofuAwsEngine bound to the resolved config and a loaded aws.Config. The Docker engine is created eagerly so a missing Docker daemon surfaces a clear error at Build time, not at construction.

func (*TofuAwsEngine) Build

func (e *TofuAwsEngine) Build(ctx context.Context, tag string) (string, error)

Build checks the Docker daemon, ensures the ECR repository exists, builds the Lambda image, pushes it, and returns the fully-qualified image URI (uri:tag).

func (*TofuAwsEngine) Deploy

func (e *TofuAwsEngine) Deploy(ctx context.Context) (map[string]string, error)

Deploy runs tofu init + apply, reads the stack outputs, and returns them as a string map. The outputs are NOT written to disk: they can carry sensitive values (ARNs, domains) and were previously persisted to gothic_outputs.json at the project root, which risked leaking into git. cmd/deploy.go prints them in a clean summary instead, and nothing in the codebase reads them back from a file.

func (*TofuAwsEngine) Destroy

func (e *TofuAwsEngine) Destroy(ctx context.Context) error

Destroy runs tofu destroy (auto-approved). It lazily initializes the tofu runner if Deploy was not called in this process.

func (*TofuAwsEngine) Prepare

func (e *TofuAwsEngine) Prepare(ctx context.Context, stage string) error

Prepare computes all resource names, bootstraps the remote state backend (S3 state bucket + DynamoDB lock table) when absent, and generates the OpenTofu working directory for the given stage.

Directories

Path Synopsis
Package docker wraps the Docker engine SDK and the AWS ECR SDK to build the Gothic Lambda image and push it to Elastic Container Registry.
Package docker wraps the Docker engine SDK and the AWS ECR SDK to build the Gothic Lambda image and push it to Elastic Container Registry.
Package tfgen generates a fully-formed OpenTofu working directory for the Gothic AWS stack.
Package tfgen generates a fully-formed OpenTofu working directory for the Gothic AWS stack.

Jump to

Keyboard shortcuts

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