Helm Releases

The helm resource type lets you deploy applications using Helm charts. Teabar handles chart fetching, value templating, and release management automatically.

Basic Usage

spec:
  resources:
    helm:
      - name: nginx-ingress
        cluster: main
        namespace: ingress-nginx
        chart: ingress-nginx/ingress-nginx
        version: 4.x

Schema Reference

helm:
  - name: string              # Required: Release name
    cluster: string           # Required: Target cluster name
    namespace: string         # Required: Target namespace
    chart: string             # Required: Chart reference (repo/chart or URL)
    version: string           # Optional: Chart version constraint
    enabled: boolean          # Optional: Enable/disable this release (default: true)
    createNamespace: boolean  # Optional: Create namespace if missing (default: true)
    atomic: boolean           # Optional: Rollback on failure (default: true)
    wait: boolean             # Optional: Wait for resources ready (default: true)
    timeout: duration         # Optional: Install/upgrade timeout (default: 10m)
    values: object            # Optional: Chart values (supports templating)
    valuesFrom:               # Optional: Load values from external sources
      - configMap: string     # ConfigMap name containing values
      - secret: string        # Secret name containing values
    repository:               # Optional: Custom repository configuration
      url: string             # Repository URL
      username: string        # Repository username
      password: string        # Repository password
    dependsOn:                # Optional: Resource dependencies
      - string                # Names of resources that must be created first

Chart Sources

Public Repositories

Reference charts from public Helm repositories:

helm:
  # Bitnami repository
  - name: postgresql
    cluster: main
    namespace: database
    chart: bitnami/postgresql
    version: 13.x

  # Prometheus community
  - name: prometheus
    cluster: main
    namespace: monitoring
    chart: prometheus-community/kube-prometheus-stack
    version: 55.x

  # GitLab
  - name: gitlab
    cluster: main
    namespace: gitlab
    chart: gitlab/gitlab
    version: 7.x

OCI Registries

Use charts from OCI-compatible registries:

helm:
  - name: my-app
    cluster: main
    namespace: apps
    chart: oci://ghcr.io/myorg/charts/myapp
    version: 1.2.0

Custom Repositories

Configure custom or private Helm repositories:

helm:
  - name: internal-app
    cluster: main
    namespace: apps
    chart: internal/myapp
    version: 2.x
    repository:
      url: https://charts.internal.example.com
      username: "{{ .Secrets.helm_repo_user }}"
      password: "{{ .Secrets.helm_repo_password }}"

Configuring Values

Inline Values

Provide values directly in the blueprint:

helm:
  - name: gitlab
    cluster: main
    namespace: gitlab
    chart: gitlab/gitlab
    version: 7.x
    values:
      global:
        edition: ce
        hosts:
          domain: "{{ .Environment.Domain }}"
          https: true
        ingress:
          configureCertmanager: true
          class: nginx
      certmanager-issuer:
        email: [email protected]
      gitlab-runner:
        runners:
          privileged: true

Templated Values

Use Go templates within values:

spec:
  variables:
    - name: gitlab_version
      type: string
      default: "16.8"
    - name: runner_count
      type: integer
      default: 2

  resources:
    helm:
      - name: gitlab
        cluster: main
        namespace: gitlab
        chart: gitlab/gitlab
        values:
          global:
            gitlabVersion: "{{ .Variables.gitlab_version }}"
            hosts:
              domain: "{{ .Environment.Domain }}"
          gitlab-runner:
            replicas: {{ .Variables.runner_count }}

Values from Secrets

Reference secrets in values:

spec:
  resources:
    secrets:
      - name: gitlab-root-password
        type: generated
        spec:
          length: 24

    helm:
      - name: gitlab
        cluster: main
        namespace: gitlab
        chart: gitlab/gitlab
        values:
          global:
            initialRootPassword:
              secret: gitlab-root-password
              key: password

Values from ConfigMaps

Load values from Kubernetes ConfigMaps:

helm:
  - name: app
    cluster: main
    namespace: apps
    chart: myorg/myapp
    valuesFrom:
      - configMap: app-values
      - secret: app-secrets
    values:
      # These override valuesFrom
      replicaCount: 3

Version Constraints

Use semantic version constraints for chart versions:

ConstraintDescriptionExample Match
1.2.3Exact version1.2.3 only
1.2.xPatch wildcard1.2.0, 1.2.5, 1.2.99
1.xMinor wildcard1.0.0, 1.5.3, 1.99.0
>=1.2.0Minimum version1.2.0, 1.5.0, 2.0.0
>=1.2.0 <2.0.0Range1.2.0, 1.9.9
~1.2.0Patch updates only1.2.0, 1.2.5
^1.2.0Compatible updates1.2.0, 1.9.9
helm:
  # Pin to exact version for production
  - name: critical-app
    chart: myorg/critical
    version: "2.1.5"

  # Allow patch updates
  - name: monitoring
    chart: prometheus-community/kube-prometheus-stack
    version: "~55.0"

  # Allow minor updates
  - name: ingress
    chart: ingress-nginx/ingress-nginx
    version: "4.x"

Common Charts

Ingress Controllers

helm:
  - name: ingress-nginx
    cluster: main
    namespace: ingress-nginx
    chart: ingress-nginx/ingress-nginx
    version: 4.x
    values:
      controller:
        service:
          type: LoadBalancer
        metrics:
          enabled: true

GitLab

helm:
  - name: gitlab
    cluster: main
    namespace: gitlab
    chart: gitlab/gitlab
    version: 7.x
    timeout: 30m
    values:
      global:
        edition: ce
        hosts:
          domain: "{{ .Environment.Domain }}"
        ingress:
          class: nginx
          configureCertmanager: true
      certmanager:
        install: false
      nginx-ingress:
        enabled: false
      prometheus:
        install: false
      gitlab-runner:
        runners:
          privileged: true
          config: |
            [[runners]]
              [runners.kubernetes]
                image = "ubuntu:22.04"

ArgoCD

helm:
  - name: argocd
    cluster: main
    namespace: argocd
    chart: argo/argo-cd
    version: 5.x
    values:
      server:
        ingress:
          enabled: true
          ingressClassName: nginx
          hosts:
            - "argocd.{{ .Environment.Domain }}"
      configs:
        params:
          server.insecure: true

Prometheus Stack

helm:
  - name: monitoring
    cluster: main
    namespace: monitoring
    chart: prometheus-community/kube-prometheus-stack
    version: 55.x
    values:
      grafana:
        adminPassword: "{{ .Resources.secrets.grafana-password.value }}"
        ingress:
          enabled: true
          ingressClassName: nginx
          hosts:
            - "grafana.{{ .Environment.Domain }}"
      prometheus:
        prometheusSpec:
          retention: 7d
          storageSpec:
            volumeClaimTemplate:
              spec:
                accessModes: ["ReadWriteOnce"]
                resources:
                  requests:
                    storage: 50Gi

Cert-Manager

helm:
  - name: cert-manager
    cluster: main
    namespace: cert-manager
    chart: jetstack/cert-manager
    version: 1.x
    values:
      installCRDs: true
      prometheus:
        enabled: true

Release Dependencies

Control the order of Helm releases:

helm:
  # Install cert-manager first
  - name: cert-manager
    cluster: main
    namespace: cert-manager
    chart: jetstack/cert-manager

  # Then ingress controller
  - name: ingress-nginx
    cluster: main
    namespace: ingress-nginx
    chart: ingress-nginx/ingress-nginx
    dependsOn:
      - cert-manager

  # Finally the application
  - name: gitlab
    cluster: main
    namespace: gitlab
    chart: gitlab/gitlab
    dependsOn:
      - ingress-nginx
      - cert-manager

Conditional Releases

Enable or disable releases based on variables:

spec:
  variables:
    - name: enable_monitoring
      type: boolean
      default: true
      ui:
        label: "Enable Monitoring"
        description: "Install Prometheus and Grafana"

  resources:
    helm:
      - name: prometheus-stack
        cluster: main
        namespace: monitoring
        chart: prometheus-community/kube-prometheus-stack
        enabled: "{{ .Variables.enable_monitoring }}"

Per-Participant Releases

While less common, you can create releases per participant:

spec:
  variables:
    - name: participant_count
      type: integer
      default: 5

  resources:
    helm:
      - name: "participant-{{ .Index }}-jupyter"
        cluster: main
        namespace: "participant-{{ .Index }}"
        chart: jupyterhub/jupyterhub
        count: "{{ .Variables.participant_count }}"
        values:
          hub:
            baseUrl: "/participant-{{ .Index }}/"

Advanced Configuration

Atomic Installs

Automatically rollback on failure:

helm:
  - name: critical-app
    cluster: main
    namespace: apps
    chart: myorg/app
    atomic: true  # Rollback if any resource fails
    wait: true    # Wait for all resources to be ready
    timeout: 15m  # Extend timeout for slow starts

Skip CRDs

For charts that install CRDs separately:

helm:
  - name: prometheus-crds
    cluster: main
    namespace: monitoring
    chart: prometheus-community/prometheus-operator-crds

  - name: prometheus
    cluster: main
    namespace: monitoring
    chart: prometheus-community/kube-prometheus-stack
    dependsOn:
      - prometheus-crds
    values:
      prometheusOperator:
        createCustomResource: false

Troubleshooting

View Release Status

# Check release status
teactl env exec my-env -- helm status gitlab -n gitlab

# View release history
teactl env exec my-env -- helm history gitlab -n gitlab

# Get computed values
teactl env exec my-env -- helm get values gitlab -n gitlab

Debug Installation

# Dry-run to see what would be deployed
teactl blueprint render my-blueprint.yaml --var enable_monitoring=true

# Check Helm template output
teactl env exec my-env -- helm template gitlab gitlab/gitlab -f values.yaml

Best Practices

  1. Pin versions - Use exact versions for production, wildcards for development
  2. Use namespaces - Isolate releases in dedicated namespaces
  3. Order dependencies - Use dependsOn to ensure correct installation order
  4. Set timeouts - Increase timeouts for charts with slow-starting pods
  5. Enable atomic - Use atomic: true for critical releases

Related Resources

ende