⚠️ Work in Progress
You are viewing development documentation built from the latest commit on main. APIs and features are subject to change.

Stack

Stack - Core Domain Model

Go Reference Go Reference

The stack package defines the hierarchical domain model at the heart of Kure. It provides the Cluster, Node, Bundle, and Application abstractions used to describe a complete Kubernetes deployment topology.

Overview

Kure models Kubernetes infrastructure as a four-level hierarchy:

Cluster
  └── Node (tree structure)
        └── Bundle (deployment unit)
              └── Application (workload)

Each level maps to a concept in GitOps deployment:

LevelPurposeGitOps Mapping
ClusterTarget clusterRoot directory
NodeOrganizational grouping (e.g., infrastructure, apps)Subdirectory tree
BundleDeployment unit with dependenciesFlux Kustomization / ArgoCD Application
ApplicationIndividual workload or resource setKubernetes manifests

Key Types

Cluster

The root of the hierarchy, representing a complete cluster configuration.

cluster := stack.NewCluster("production", rootNode)
cluster.SetGitOps(&stack.GitOpsConfig{
    Type: "flux",
})

Node

A tree structure for organizing bundles into logical groups. Nodes can have children (sub-nodes) and a package reference for multi-source deployments.

node := &stack.Node{
    Name:     "infrastructure",
    Children: []*stack.Node{childNode},
    Bundle:   []*stack.Bundle{monitoringBundle},
}

Bundle

A deployment unit corresponding to a single GitOps resource (e.g., a Flux Kustomization). Bundles support dependency ordering via DependsOn.

bundle, err := stack.NewBundle("monitoring", apps, labels)
bundle.DependsOn = []string{"cert-manager"}
bundle.Interval = "10m"

Bundles also support an umbrella pattern via Bundle.Children. When a bundle has non-empty Children, its generated Flux Kustomization automatically gets spec.wait: true plus an entry in spec.healthChecks for each child, giving external consumers a single readiness anchor for a group of bundles. The child bundles’ Flux Kustomization CRs are rendered into the parent bundle’s directory. Children must be standalone bundles — they cannot simultaneously be attached as the Bundle of any stack.Node.

Bundle.HealthChecks can also be set explicitly to monitor specific resources during reconciliation:

bundle.HealthChecks = []stack.HealthCheck{
    {APIVersion: "apps/v1", Kind: "Deployment", Name: "web", Namespace: "default"},
}

When Children is non-empty, health checks for each child Kustomization are auto-generated and merged with any user-supplied entries.

Validation: ValidateCluster() runs automatically in all layout entry points (WalkCluster, WalkClusterByPackage) and rejects invalid umbrella configurations (e.g., shared ownership, children that are also node bundles).

Application

An individual Kubernetes workload. Applications use the ApplicationConfig interface to generate their resources.

app := stack.NewApplication("prometheus", "monitoring", prometheusConfig)
resources, err := app.Generate()

ApplicationConfig Interface

Implement this interface to define how an application generates its Kubernetes resources:

type ApplicationConfig interface {
    Generate(*Application) ([]*client.Object, error)
}

Optional Validation

ApplicationConfig implementations can optionally implement the Validator interface to validate configuration before resource generation:

type Validator interface {
    Validate() error
}

When present, Application.Generate() calls Validate() automatically before Generate(). If validation fails, generation stops and the error is returned with application context:

type myConfig struct { Port int }

func (c *myConfig) Validate() error {
    if c.Port <= 0 {
        return errors.New("port must be positive")
    }
    return nil
}

func (c *myConfig) Generate(app *stack.Application) ([]*client.Object, error) {
    // Only called if Validate() passes (or is not implemented)
    ...
}

Validation errors are wrapped with application name and namespace:

validation failed for application "web" in namespace "prod": port must be positive

Configs that do not implement Validator continue to work without changes.

Fluent Builder API

For ergonomic cluster construction, use the fluent builder. Builder methods use copy-on-write semantics — each With* call returns a new builder instance, leaving the original unchanged:

cluster := stack.NewClusterBuilder("production").
    WithNode("infrastructure").
        WithBundle("monitoring").
            WithApplication("prometheus", appConfig).
        End().
    End().
    Build()

Workflow System

The package provides a pluggable workflow abstraction for GitOps tool integration:

// Create a workflow for your GitOps tool
wf, err := stack.NewWorkflow("flux")

// Generate GitOps resources from the cluster definition
objects, err := wf.GenerateFromCluster(cluster)

Supported workflow providers: "flux" / "fluxcd" and "argo" / "argocd".

Source References

Bundles and nodes can reference different source types for multi-source deployments:

node.SetPackageRef(&stack.SourceRef{
    Kind:      "OCIRepository",
    Name:      "my-registry",
    Namespace: "flux-system",
    URL:       "oci://registry.example.com/manifests",
    Tag:       "v1.0.0",
})