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
- func GraphFromArtifacts(artifacts []architecturev2renderer.Artifact) (terramatestackgraph.Graph, error)
- func MissingCoreRoots(workspaceRoot string, layout Layout) ([]string, error)
- func ReplaceTriggerAddress(mainTF []byte) (string, error)
- func SelectHost(graph terramatestackgraph.Graph, siteRef, nodeRef string) (terramatestackgraph.Host, error)
- type ConvergeRequest
- type Error
- type ErrorCode
- type EventFunc
- type FileRecord
- type Layout
- type Manifest
- type ManifestStack
- type MaterializeResult
- type Report
- type StackPlan
- type StackResult
- type StackTofuRequest
- type StackTofuResult
- type Tools
Constants ¶
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" )
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.
const ( ResultConverged = "converged" ResultNotConverged = "not_converged" )
Overall statuses of a change-set result.
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 ¶
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 ¶
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 ¶
Error is the structured orchestration failure. Stacks names the affected stack IDs that caused it.
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" )
type EventFunc ¶
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 ¶
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.
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 ¶
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 ¶
Tools are the packaged binaries a host project runs with.
func PackagedTools ¶
PackagedTools resolves the release-packaged Terramate and OpenTofu binaries (STACKKIT_TERRAMATE_BINARY and STACKKIT_TOFU_BINARY override them). It never falls back to PATH.