Stack
Stack - Core Domain Model
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:
| Level | Purpose | GitOps Mapping |
|---|---|---|
| Cluster | Target cluster | Root directory |
| Node | Organizational grouping (e.g., infrastructure, apps) | Subdirectory tree |
| Bundle | Deployment unit with dependencies | Flux Kustomization / ArgoCD Application |
| Application | Individual workload or resource set | Kubernetes 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 positiveConfigs 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",
})Related Packages
- stack/fluxcd - FluxCD workflow engine implementation
- stack/generators - Application generator system
- stack/layout - Manifest directory organization