Introduction to Helmsman
Helmsman is an open-source tool that lets you manage and automate Helm chart deployments (“Helm charts as code”) using a single, version-controlled configuration file. It offers:
- Declarative desired state for your Kubernetes applications
- Automated deployment, upgrade, and deletion of Helm releases
- Drift detection, plan/apply workflows, and dry runs
- Release ordering, RBAC, policy management, and multi-environment support
- Support for secrets, CI/CD, and GitOps workflows
Advantages over raw Helm and similar tools:
- Centralizes and codifies all Helm releases and configurations
- Enables idempotent, repeatable deployments
- Supports release dependencies, priorities, and advanced orchestration
- Integrates with CI/CD and GitOps practices easily
Installation and Setup
Prerequisites
- kubectl (configured for your cluster)
- Helm (v3.0.0+ recommended)
- helm-diff plugin (for diff/plan features)
- Optional: helm-secrets, helm-s3, or helm-gcs plugins for private repos or secrets
Install Helmsman
macOS:
textbrew install helmsman
Linux:
textcurl -L https://github.com/mkubaczyk/helmsman/releases/download/v4.0.1/helmsman_4.0.1_linux_amd64.tar.gz | tar zx
sudo mv helmsman /usr/local/bin/helmsman
Docker:
textdocker pull ghcr.io/mkubaczyk/helmsman:latest
docker run --rm -it -v $PWD:/wd -w /wd ghcr.io/mkubaczyk/helmsman:latest helmsman --help
Other options: Archlinux packages, asdf-vm plugin, or direct binary downloads.
Helmsman Desired State File (DSF) Structure
Helmsman uses a desired state file (DSF) in TOML or YAML format. The DSF defines:
- Helm repositories
- Namespaces
- Applications (Helm releases)
- Settings (global options)
- Policies, RBAC, and more
Minimal YAML Example:
texthelmRepos:
stable: https://charts.helm.sh/stable
namespaces:
dev:
prod:
apps:
nginx:
chart: stable/nginx
version: 1.2.3
namespace: dev
valuesFile: ./values/nginx-dev.yaml
enabled: true
Minimal TOML Example:
text[helmRepos]
stable = "https://charts.helm.sh/stable"
[namespaces]
dev = {}
prod = {}
[apps.nginx]
chart = "stable/nginx"
version = "1.2.3"
namespace = "dev"
valuesFile = "./values/nginx-dev.yaml"
enabled = true
For full DSF specification, see the [official docs].
Creating and Managing Simple Helm Releases
- Create your DSF (YAML or TOML as above).
- Dry-run/plan the deployment: text
helmsman -f myfile.yamlThis shows what will change, without applying it. - Apply the desired state: text
helmsman --apply -f myfile.yamlThis will install/upgrade/delete releases as needed.
Organizing Projects with Multiple Releases, Namespaces, and Charts
- Multiple apps: Add more entries under
apps. - Multiple namespaces: Define under
namespacesand assign to each app. - Multiple values files: Use
valuesFiles(array) for each app.
Example:
textnamespaces:
dev:
prod:
apps:
frontend:
chart: stable/nginx
namespace: dev
valuesFiles: ["./values/frontend-dev.yaml"]
backend:
chart: stable/postgresql
namespace: prod
valuesFiles: ["./values/backend-prod.yaml"]
Setting Up Priorities and Controlling Release Ordering
Helmsman uses the priority field to control the order of release deployments:
- Lower (more negative) values = higher priority (executed first)
- Default priority is 0
Example:
textapps:
db:
chart: stable/postgresql
priority: -10
app:
chart: stable/nginx
priority: 0
Here, db will be deployed before app.
Implementing RBAC and Policy Management
Helmsman can manage RBAC and policies at the namespace level:
textnamespaces:
dev:
protected: true
installTiller: false
serviceAccount: "myserviceaccount"
owner: "devops-team"
protected: trueprevents accidental deletion of releases in this namespace.- Assign RBAC roles/policies as needed in your DSF.
Using Drift Detection, Plan/Apply Workflows, and Dry Runs
- Plan (show intended actions): text
helmsman -f myfile.yaml - Apply (execute actions): text
helmsman --apply -f myfile.yaml - Dry-run: text
helmsman --dry-run -f myfile.yaml - Show diff: (requires helm-diff) text
helmsman --apply --debug -f myfile.yaml
Helmsman detects drift between your desired state and the actual cluster state, and only applies necessary changes.
Integrating Secrets and Managing Configuration Securely
- Environment variables: Reference in values files or DSF using templating.
- Secrets: Use
helm-secretsplugin to reference encrypted secrets in values files. - Private repos: Use
helm-s3orhelm-gcsplugins and configure authentication in your DSF.
Managing Environments and Release Conditions
- Multiple environments: Use separate DSFs (e.g.,
dev.yaml,prod.yaml), or merge files: texthelmsman -f common.yaml -f dev.yaml --applyLater files override earlier ones. - Release conditions: Use the
enabledflag or environment variables to conditionally deploy releases.
Moving releases across namespaces: Change the namespace field for an app; Helmsman will delete it from the old namespace and install in the new one.
Incorporating Helmsman into CI/CD and GitOps Workflows
- Store DSFs in Git for version control.
- CI/CD pipeline example: text
helmsman --apply -f prod.yaml - ns-override flag: Deploy all apps to a specific namespace in CI (e.g., for staging/dev branches).
- Context stanza: Use the
contextfield to isolate DSFs managing different clusters/environments.
Troubleshooting, Debugging, and Best Practices
- Debugging: Use
--debugflag for verbose output. - Dry runs: Always dry-run before applying in production.
- Split DSFs: Use multiple files for base/common and environment-specific configs.
- Context management: Set
contextin DSFs to avoid releases being deleted by other DSFs. - Namespace protection: Use
protected: trueto safeguard critical namespaces. - Labeling: Use meaningful app and namespace names for clarity.
Real-World Example and Sample Configuration
Project structure:
text.
├── common.yaml
├── dev.yaml
├── prod.yaml
└── values/
├── frontend-dev.yaml
├── frontend-prod.yaml
└── backend-prod.yaml
common.yaml:
texthelmRepos:
stable: https://charts.helm.sh/stable
namespaces:
dev:
protected: true
prod:
protected: true
dev.yaml:
textapps:
frontend:
chart: stable/nginx
namespace: dev
valuesFiles: ["./values/frontend-dev.yaml"]
enabled: true
priority: -5
prod.yaml:
textapps:
frontend:
chart: stable/nginx
namespace: prod
valuesFiles: ["./values/frontend-prod.yaml"]
enabled: true
priority: -5
backend:
chart: stable/postgresql
namespace: prod
valuesFiles: ["./values/backend-prod.yaml"]
enabled: true
priority: -10
Deploy to dev:
texthelmsman -f common.yaml -f dev.yaml --apply
Deploy to prod:
texthelmsman -f common.yaml -f prod.yaml --apply
Comparison: Helmsman vs. Helmfile vs. Helmwave
| Feature | Helmsman | Helmfile | Helmwave |
|---|---|---|---|
| Syntax | TOML/YAML | YAML + sprig | YAML + sprig/gomplate |
| Parallel Deployments | No | Yes | Yes |
| Release Dependencies | Priority-based | needs | depends_on |
| Drift Detection | Yes | Yes | Yes |
| Secret Management | helm-secrets | helm-secrets | gomplate/external |
| Plan/Apply Workflow | Yes | Yes | Yes |
| Live Resource Tracking | No | No | Yes (kubedog) |
| Multi-env Management | Strong | Strong | Strong |
| Helm Integration | Native | Native | Bundled |
When to choose Helmsman:
- Prefer TOML/YAML config and clear, declarative desired state
- Need robust drift detection and plan/apply workflows
- Simpler release ordering (priority-based)
- Want a lightweight, CI/CD-friendly tool with minimal dependencies
Helmsman is a powerful, beginner-friendly, and automation-focused tool for managing Helm releases at scale. Its declarative approach, environment management, and CI/CD integration make it a strong choice for teams seeking reliable, repeatable Kubernetes deployments.