Skip to content

Helmfile Reference: Multi-Helm Release Management, Environments, Secrets & Hooks

Helmfile declaratively manages multiple Helm releases across environments. Instead of running helm install commands manually or writing wrapper scripts, you define all your Helm charts, values, and environments in a single helmfile.yaml — then sync them all with one command.

1. Install & Basic Structure

Install Helmfile and understand the core config file
# Install:
brew install helmfile      # macOS
# Or: https://github.com/helmfile/helmfile/releases (single binary)

# helmfile.yaml — basic structure:
repositories:
  - name: stable
    url: https://charts.helm.sh/stable
  - name: bitnami
    url: https://charts.bitnami.com/bitnami

releases:
  - name: nginx-ingress
    chart: ingress-nginx/ingress-nginx
    version: 4.9.0
    namespace: ingress-nginx
    createNamespace: true
    values:
      - controller.replicaCount: 2
        controller.service.type: LoadBalancer

  - name: cert-manager
    chart: jetstack/cert-manager
    version: v1.14.0
    namespace: cert-manager
    createNamespace: true
    set:
      - name: installCRDs
        value: true

  - name: my-app
    chart: ./charts/my-app          # local chart
    namespace: production
    values:
      - values/production.yaml      # values file (relative to helmfile.yaml)

# Core commands:
helmfile sync        # install/upgrade all releases to match helmfile.yaml
helmfile apply       # like sync but diffs first (safer in CI)
helmfile diff        # show what would change (no changes applied)
helmfile destroy     # uninstall all releases
helmfile list        # list all releases + status
helmfile status      # detailed status per release

2. Environments

Different config for dev, staging, and production
# helmfile.yaml with environments:
environments:
  default:
    values:
      - values/common.yaml
  staging:
    values:
      - values/common.yaml
      - values/staging.yaml
  production:
    values:
      - values/common.yaml
      - values/production.yaml
    secrets:
      - secrets/production.yaml.dec   # decrypted by helm-secrets

releases:
  - name: my-app
    chart: ./charts/my-app
    namespace: "{{ .Values.namespace }}"   # from environment values
    values:
      - replicaCount: "{{ .Values.replicaCount }}"
        image.tag: "{{ .Values.imageTag }}"

# values/staging.yaml:
namespace: staging
replicaCount: 1
imageTag: staging-latest

# values/production.yaml:
namespace: production
replicaCount: 3
imageTag: v1.4.2

# Deploy to specific environment:
helmfile --environment production sync
helmfile --environment staging diff

# Environment-conditional releases (only deploy monitoring in production):
releases:
  - name: prometheus-stack
    chart: prometheus-community/kube-prometheus-stack
    condition: monitoring.enabled    # enabled/disabled via environment values

3. Selectors & Targeting

Deploy only specific releases from a large helmfile
# Label releases for selective targeting:
releases:
  - name: nginx-ingress
    chart: ingress-nginx/ingress-nginx
    labels:
      tier: infrastructure
      app: ingress

  - name: my-app
    chart: ./charts/my-app
    labels:
      tier: application
      team: backend

  - name: monitoring
    chart: prometheus-community/kube-prometheus-stack
    labels:
      tier: monitoring

# Deploy only application tier:
helmfile --selector tier=application sync

# Deploy only a specific release:
helmfile --selector name=my-app sync
helmfile --selector name=my-app diff

# Deploy multiple labels (AND condition):
helmfile --selector tier=application,team=backend sync

# Useful for:
# - Deploying infrastructure separately from applications
# - Updating only the changed service in a large cluster
# - Running diff on specific releases in CI

4. Secrets with helm-secrets

Encrypt secrets in helmfile.yaml using SOPS or Vault
# Install helm-secrets plugin:
helm plugin install https://github.com/jkroepke/helm-secrets

# Encrypt a values file with SOPS + age key:
sops --age $(cat age-key.pub) --encrypt values/secrets.yaml > values/secrets.enc.yaml

# Reference encrypted file in helmfile:
releases:
  - name: my-app
    chart: ./charts/my-app
    secrets:
      - values/secrets.enc.yaml      # helmfile auto-decrypts via helm-secrets

# .sops.yaml (encryption rules):
creation_rules:
  - path_regex: secrets/.*\.enc\.yaml
    age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Environment-level secrets:
environments:
  production:
    secrets:
      - secrets/production.enc.yaml   # decrypted before rendering

# Vault as secret backend:
# helm secrets vault decrypt values/secrets.yaml
# Reference vault paths in values:
# db_password: "ref+vault://secret/production/myapp#db_password"

5. Hooks & Advanced Patterns

Pre/post hooks, needs ordering, and chart dependencies
# needs: deploy releases in dependency order
releases:
  - name: cert-manager
    chart: jetstack/cert-manager
    needs:
      - ingress-nginx              # wait for ingress to be ready first

  - name: ingress-nginx
    chart: ingress-nginx/ingress-nginx

  - name: my-app
    chart: ./charts/my-app
    needs:
      - cert-manager               # wait for cert-manager CRDs

# Hooks (run kubectl or helm commands before/after release):
releases:
  - name: my-app
    chart: ./charts/my-app
    hooks:
      - events: [presync]
        command: kubectl
        args: [apply, -f, crds/]   # apply CRDs before installing chart
      - events: [postsync]
        command: kubectl
        args: [rollout, status, deployment/my-app, -n, production]

# Template rendering (Go templates in helmfile.yaml):
releases:
  - name: my-app
    chart: ./charts/my-app
    set:
      - name: gitSHA
        value: {{ exec "git" (list "rev-parse" "--short" "HEAD") | trim }}

# CI/CD usage:
# helmfile diff --detailed-exitcode   # exit 1 if diff exists (use for PR checks)
# helmfile apply                       # apply only changed releases
# helmfile test                        # run helm test on all releases

Track Helmfile, Helm, and Kubernetes tooling releases.
ReleaseRun monitors Kubernetes, Docker, and 13+ DevOps technologies.

Related: Kubernetes YAML Reference | Kustomize Reference | ArgoCD Reference

🔍 Free tool: K8s YAML Security Linter — after helmfile template, paste the rendered output here to check 12 K8s security misconfigurations.

Founded

2023 in London, UK

Contact

hello@releaserun.com