Helm Modules
How to define, build, and deploy Helm charts with strata.
Overview
Strata handles the full Helm lifecycle: define → build → deploy. You define what you want in YAML, strata builds self-contained artifacts, then deploys them to your Kubernetes cluster.
strata build run --file config/deploy-prod.yaml → artifacts
strata deploy run --file config/deploy-prod.yaml → helm upgrade --install
Defining a Helm Module
A module YAML tells strata: “I want this chart, at this version, with these values, deployed to this namespace.”
Registry chart (third-party)
apiVersion: strata.huybrechts.xyz/v1
kind: module
meta:
name: argocd
annotations:
description: Argo CD — GitOps continuous delivery
spec:
source:
chart_name: argo-cd
chart_version: "7.8.0"
chart_repository: https://argoproj.github.io/argo-helm
type: helm
release_name: argocd
kubernetes_namespace: argocd
files:
- source: services/forge/argocd/values.yaml
target: values.yaml
Local chart (your own)
apiVersion: strata.huybrechts.xyz/v1
kind: module
meta:
name: my-app
spec:
source:
repository: my-repo
source_path: services/my-app/helm
type: helm
release_name: my-app
kubernetes_namespace: apps
files:
- source: services/my-app/values-prd.yaml
target: values.yaml
Source modes
Mode |
Fields |
When to use |
|---|---|---|
Registry chart |
|
Third-party charts (ArgoCD, nginx-ingress, cert-manager, etc.) |
Local chart |
|
Your own Helm charts stored in a config repo |
Spec fields reference
Field |
Purpose |
Default |
|---|---|---|
|
Helm release name |
|
|
Target Kubernetes namespace |
Strata namespace name |
|
Extra helm values merged into |
— |
|
Files to copy into build output (values, etc.) |
— |
|
Structured service definitions → generates |
— |
Wiring into a Deployment
1. Namespace references the module
apiVersion: strata.huybrechts.xyz/v1
kind: namespace
meta:
name: forge
spec:
modules:
- name: argocd
file: config/forge/modules/mod-argocd.yaml
2. Workspace topology references the namespace
# In workspace spec.topologies:
- name: hetzner_forge
provider: hetzner_dc_eu_de
provisioner: haven_iac
type: single_node
namespaces:
- namespace: forge
3. Deployment stage references the topology
# In deployment spec.stages:
- name: services_forge
topology: hetzner_forge
scope: all
depends_on: infrastructure_forge
on_failure: stop
Build Output
strata build run --file config/deploy-prod.yaml
Produces a self-contained artifact per module:
build/<deployment>/<namespace>/<module>/
├── meta.yaml ← deployment identity + chart coordinates
└── values.yaml ← helm values
meta.yaml
Contains everything needed to deploy — no source YAML required at deploy time:
releaseName: argocd
namespace: argocd
chartName: argo-cd
chartVersion: "7.8.0"
chartRepository: https://argoproj.github.io/argo-helm
For local charts, chartName/chartVersion/chartRepository are absent.
The deployer uses the build directory as the chart reference instead.
values.yaml
Helm values assembled from three possible sources (in merge order):
Source |
Use case |
|---|---|
|
Structured definitions (env vars, mounts, ports) → generated values |
|
Extra top-level values merged on top |
|
Hand-crafted values.yaml copied verbatim |
For registry charts without services (like ArgoCD), use files to provide
your own values.yaml. For your own apps with structured services, use
services + optionally configuration for overrides.
Deploy
strata deploy run --file config/deploy-prod.yaml
What executes
Step |
Command |
Purpose |
|---|---|---|
setup |
|
Register chart repositories |
plan |
|
Preview changes without applying |
apply |
|
Install or upgrade the release |
Safety flags
--wait— blocks until all pods are Running (not just submitted)--atomic— automatically rolls back if the deploy fails--timeout 5m— gives complex charts time to stabilize--create-namespace— creates the target namespace if it doesn’t exist
Dry-run only
strata deploy run --file config/deploy-prod.yaml --plan-only
Destroy
strata deploy run --file config/deploy-prod.yaml --destroy --force
Runs helm uninstall <release> --namespace <namespace> for each module.
GitOps Integration
Strata deploys Helm charts directly. It does not generate ArgoCD
Application CRs or Flux HelmRelease CRs — that is out of scope.
If you want GitOps after deploying ArgoCD:
Monitoring mode: ArgoCD discovers existing helm releases strata deployed (zero extra config)
Application CRs: Write them yourself —
meta.yamlhas all the fields you need to fill in the templateApp-of-apps: Maintain an umbrella chart that generates Applications from strata’s values files
Git generator: Point ArgoCD’s
ApplicationSetat the build output directory
Strata’s role: deploy ArgoCD. ArgoCD’s role: manage everything else.
Examples
Minimal — deploy a registry chart with custom values
spec:
source:
chart_name: nginx-ingress
chart_version: "4.10.0"
chart_repository: https://kubernetes.github.io/ingress-nginx
type: helm
release_name: ingress
kubernetes_namespace: ingress-nginx
files:
- source: services/ingress/values.yaml
target: values.yaml
Structured services — generate values from definitions
spec:
source:
repository: my-repo
source_path: charts/my-app
type: helm
release_name: my-app
kubernetes_namespace: production
services:
- name: api
image: my-app:1.2.0
environment:
- key: DATABASE_URL
secret: DB_URL
- key: LOG_LEVEL
value: info
mounts:
- name: data
storage_class: fast-ssd
storage_size: 10Gi
target_path: /var/data
configuration:
replicaCount: 3
resources:
limits:
memory: 512Mi
Produces:
# values.yaml (generated)
my-app-api:
env:
DATABASE_URL: "${DB_URL}"
LOG_LEVEL: info
persistence:
data:
storageClass: fast-ssd
accessMode: ReadWriteOnce
size: 10Gi
replicaCount: 3
resources:
limits:
memory: 512Mi