terramatehost

package
v0.46.7 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package terramatehost materializes the Terramate host project of one node and runs the packaged Terramate binary over it (ADR-0045 section 2 and section 5, docs/ARCHITECTURE.md "Advanced change sets through Terramate (Stage 1)").

A host project is the executor-managed runtime tree `.stackkit/runtime` of the workspace. Generation renders the project root (`terramate.tm.hcl`, owned by the Core host bootstrap module) and one `stack.tm.hcl` per stack as artifact-only files; this package places them where the stack graph says: the root file at `.stackkit/runtime/terramate.tm.hcl` and every stack file in its stack's runtime root, next to the OpenTofu `main.tf` that the runtime executor installs. Placement is derived from the graph and the rendered bytes only, so it is deterministic and the manifest digest can be computed before any write (change-set create) and proven again after (apply).

Index

Constants

View Source
const (
	// ResultSchemaVersion identifies the per-stack change-set result
	// (schemas/stackkit-change-set-result-v1.schema.json).
	ResultSchemaVersion = "stackkit.change-set-result/v1"
	// StackTags selects every StackKits stack of a host project.
	StackTags = "stackkit"
)
View Source
const (
	// StackConverged: `tofu plan -detailed-exitcode` exited 0 after apply.
	StackConverged = "converged"
	// StackDrifted: the plan exited 2, so the applied root still differs from
	// its configuration. The change set fails and rolls back.
	StackDrifted = "drifted"
	// StackFailed: the plan could not run (exit 1 or a Terramate error).
	StackFailed = "failed"
	// StackPendingRoot: the runtime root has no `main.tf` yet. Tolerated only
	// for artifact-only roles (edge, federation), whose roots the executor
	// does not materialize yet; a core or workload root must exist.
	StackPendingRoot = "pending_root"
	// StackOtherHost: the stack belongs to another host project. Its change
	// runs through that host's execution channel (Techstack dispatch).
	StackOtherHost = "other_host"
)

Per-stack statuses of a change-set result.

View Source
const (
	ResultConverged    = "converged"
	ResultNotConverged = "not_converged"
)

Overall statuses of a change-set result.

View Source
const (
	// ManifestAPIVersion identifies the host manifest document.
	ManifestAPIVersion = "stackkit.terramate-host-manifest/v1"
	// ManifestPath is the workspace-relative manifest location. It sits
	// beside, not inside, the runtime tree, so it never becomes part of the
	// Terramate project.
	ManifestPath = ".stackkit/terramate-host-manifest.json"
	// RootConfigFile is the Terramate project root configuration.
	RootConfigFile = "terramate.tm.hcl"
	// StackFile is the Terramate stack definition inside each runtime root.
	StackFile = "stack.tm.hcl"
	// OpenTofuConfigFile is the OpenTofu root module file the runtime
	// executor installs in a stack's runtime root.
	OpenTofuConfigFile = "main.tf"
)

Variables

This section is empty.

Functions

func GraphFromArtifacts

func GraphFromArtifacts(artifacts []architecturev2renderer.Artifact) (terramatestackgraph.Graph, error)

GraphFromArtifacts parses the plan-owned stack graph among rendered artifacts. A render without a graph is not a `terramate` target render.

func MissingCoreRoots

func MissingCoreRoots(workspaceRoot string, layout Layout) ([]string, error)

MissingCoreRoots returns the IDs of the layout's core stacks whose runtime root has no `main.tf`. Only the runtime executor creates core roots, so a host project with a missing core root must not be materialized.

func ReplaceTriggerAddress

func ReplaceTriggerAddress(mainTF []byte) (string, error)

ReplaceTriggerAddress returns the `terraform_data` resource whose replacement forces a wrapper root to run `docker compose up` against its current payload. A root with a dedicated `<prefix>_up` resource (the split up/lifecycle layout) names that one, so the trigger never runs the destroy-time `down`; an older root with a single `terraform_data` resource names that resource.

func SelectHost

func SelectHost(graph terramatestackgraph.Graph, siteRef, nodeRef string) (terramatestackgraph.Host, error)

SelectHost returns the graph host of siteRef/nodeRef. Empty refs select the only host of a single-host graph.

Types

type ConvergeRequest

type ConvergeRequest struct {
	WorkspaceRoot string
	ChangeSetID   string
	Layout        Layout
	// ExpectedManifestSHA256 is the host manifest digest recorded by the
	// change set. A different layout fails before any write.
	ExpectedManifestSHA256 string
	// AffectedStacks are the change set's stack IDs in graph run order.
	AffectedStacks []string
	Tools          Tools
	Timeout        time.Duration
	Event          EventFunc
}

ConvergeRequest is one post-apply Terramate orchestration of a change set on the local host.

type Error

type Error struct {
	Code   ErrorCode
	Stacks []string
	Detail string
	Err    error
}

Error is the structured orchestration failure. Stacks names the affected stack IDs that caused it.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type ErrorCode

type ErrorCode string

ErrorCode classifies a failed Terramate orchestration.

const (
	// ErrToolMissing: the packaged Terramate or OpenTofu binary is absent.
	ErrToolMissing ErrorCode = "terramate_tool_missing"
	// ErrHostDiverged: the host layout differs from the one the change set
	// was approved with.
	ErrHostDiverged ErrorCode = "terramate_host_diverged"
	// ErrRunOrder: `terramate list --run-order` disagrees with the graph.
	ErrRunOrder ErrorCode = "terramate_run_order_mismatch"
	// ErrNotConverged: at least one affected stack failed its post-apply
	// convergence plan, lacks a required root, or drifted.
	ErrNotConverged ErrorCode = "advanced_change_set_not_converged"
)

func Reason

func Reason(err error) (ErrorCode, bool)

Reason returns the structured code of an orchestration error.

type EventFunc

type EventFunc func(phase, status string, attributes map[string]string)

EventFunc receives orchestration progress: phase is one of materialize-host, run-order or converge; status is started, succeeded, failed or, for converge, the per-stack status.

type FileRecord

type FileRecord struct {
	Path   string `json:"path"`
	SHA256 string `json:"sha256"`
}

FileRecord binds one placed file to its bytes.

type Layout

type Layout struct {
	Graph          terramatestackgraph.Graph
	Host           terramatestackgraph.Host
	Manifest       Manifest
	ManifestBytes  []byte
	ManifestSHA256 string
	// contains filtered or unexported fields
}

Layout is the complete, not yet written host project of one node.

func Plan

func Plan(graph terramatestackgraph.Graph, artifacts map[string][]byte, siteRef, nodeRef string) (Layout, error)

Plan derives the host layout from the graph and the rendered bytes keyed by artifact ID. It performs no I/O.

func PlanFromArtifacts

func PlanFromArtifacts(artifacts []architecturev2renderer.Artifact, siteRef, nodeRef string) (Layout, error)

PlanFromArtifacts derives the host layout of siteRef/nodeRef from one rendered `terramate` target render.

func (Layout) Stack

func (layout Layout) Stack(id string) (terramatestackgraph.Stack, bool)

Stack returns the graph stack with id.

type Manifest

type Manifest struct {
	APIVersion          string          `json:"apiVersion"`
	StackID             string          `json:"stackId"`
	PlanHash            string          `json:"planHash"`
	SiteRef             string          `json:"siteRef"`
	NodeRef             string          `json:"nodeRef"`
	ExecutionChannelRef string          `json:"executionChannelRef,omitempty"`
	ProjectRoot         string          `json:"projectRoot"`
	RootConfig          FileRecord      `json:"rootConfig"`
	RunOrder            []string        `json:"runOrder"`
	Stacks              []ManifestStack `json:"stacks"`
}

Manifest is the `stackkit.terramate-host-manifest/v1` record of one host project. It holds no time or machine facts, so equal inputs produce byte-identical manifests and digests.

type ManifestStack

type ManifestStack struct {
	ID           string     `json:"id"`
	Role         string     `json:"role"`
	RuntimeRoot  string     `json:"runtimeRoot"`
	OpenTofuRoot string     `json:"openTofuRoot"`
	StackFile    FileRecord `json:"stackFile"`
}

ManifestStack is one stack of the host project.

type MaterializeResult

type MaterializeResult struct {
	Written        []string `json:"written"`
	ManifestSHA256 string   `json:"manifestSha256"`
}

MaterializeResult reports which workspace-relative files were written. A second materialization of the same layout writes nothing.

func Materialize

func Materialize(workspaceRoot string, layout Layout) (MaterializeResult, error)

Materialize places the layout under workspaceRoot. It creates missing runtime roots (the executor may not have installed `main.tf` yet), rewrites a file only when its bytes differ, refuses symlinks and non-regular files on the way, and writes the manifest last.

type Report

type Report struct {
	SchemaVersion      string        `json:"schemaVersion"`
	ChangeSetID        string        `json:"changeSetId"`
	StackID            string        `json:"stackId"`
	PlanHash           string        `json:"planHash"`
	SiteRef            string        `json:"siteRef"`
	NodeRef            string        `json:"nodeRef"`
	ProjectRoot        string        `json:"projectRoot"`
	HostManifestSHA256 string        `json:"hostManifestSha256"`
	Materialized       []string      `json:"materialized"`
	RunOrder           []string      `json:"runOrder"`
	AffectedStacks     []string      `json:"affectedStacks"`
	Status             string        `json:"status"`
	Stacks             []StackResult `json:"stacks"`
}

Report is the `stackkit.change-set-result/v1` document.

func Converge

func Converge(ctx context.Context, request ConvergeRequest) (Report, error)

Converge materializes the host project, proves that Terramate orders the host stacks exactly as the graph does, and runs `terramate run --no-recursive --tags stackkit -- tofu plan -detailed-exitcode -input=false` in every affected local stack root, in run order. It only reads OpenTofu state: the apply already happened through the runtime executor. The report is returned on every path after validation, so a failed change set still records what each stack showed.

type StackPlan

type StackPlan struct {
	Result StackResult
	// Stdout is the plan output; empty when the plan did not run.
	Stdout string
}

StackPlan is one read-only detailed-exitcode plan of a local stack outside a change set (per-stack drift detection, docs/ARCHITECTURE.md "Advanced drift per stack (Stage 1)").

func PlanLocalStack

func PlanLocalStack(ctx context.Context, workspaceRoot string, layout Layout, tools Tools, timeout time.Duration, stack terramatestackgraph.Stack) (StackPlan, error)

PlanLocalStack runs `terramate run --no-recursive --tags stackkit -- tofu plan -detailed-exitcode -input=false -no-color` in one stack root of the layout's host, with the same process environment as Converge. It never applies. The host project must already be materialized.

type StackResult

type StackResult struct {
	StackID      string `json:"stackId"`
	Role         string `json:"role"`
	SiteRef      string `json:"siteRef"`
	NodeRef      string `json:"nodeRef"`
	RuntimeRoot  string `json:"runtimeRoot"`
	Status       string `json:"status"`
	PlanExitCode *int   `json:"planExitCode,omitempty"`
	DurationMS   int64  `json:"durationMs"`
	Detail       string `json:"detail,omitempty"`
}

StackResult is the outcome of one affected stack.

type StackTofuRequest

type StackTofuRequest struct {
	WorkspaceRoot string
	Tools         Tools
	// RuntimeRoot is the workspace-relative stack runtime root
	// (.stackkit/runtime/.../opentofu).
	RuntimeRoot string
	// Env is added to the process environment, for example the Compose
	// interpolation environment a wrapper root's local-exec needs.
	Env     []string
	Timeout time.Duration
}

StackTofuRequest runs one OpenTofu command in one local stack root through `terramate run --no-recursive --tags stackkit`, with the same process environment as the change-set convergence plan (docs/ARCHITECTURE.md "Coordinated rollback across stacks (Stage 1)").

type StackTofuResult

type StackTofuResult struct {
	ExitCode   int
	Detail     string
	DurationMS int64
}

StackTofuResult is the relayed OpenTofu exit code and bounded stderr.

func RunStackTofu

func RunStackTofu(ctx context.Context, request StackTofuRequest, args ...string) (StackTofuResult, error)

RunStackTofu runs `terramate run --no-recursive --tags stackkit -- tofu <args>` in request.RuntimeRoot. A non-zero OpenTofu exit code is returned in the result, not as an error; an error means Terramate could not run it.

type Tools

type Tools struct {
	Terramate string
	Tofu      string
}

Tools are the packaged binaries a host project runs with.

func PackagedTools

func PackagedTools() (Tools, error)

PackagedTools resolves the release-packaged Terramate and OpenTofu binaries (STACKKIT_TERRAMATE_BINARY and STACKKIT_TOFU_BINARY override them). It never falls back to PATH.

Jump to

Keyboard shortcuts

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