The Complete Guide to Helm

    From Beginner to Expert

    Table of Contents

    1. Introduction to Helm
    2. Getting Started
    3. Understanding Helm Architecture
    4. Charts: The Heart of Helm
    5. Templates and Values
    6. Helm Commands and CLI
    7. Managing Dependencies
    8. Advanced Templating
    9. Hooks and Tests
    10. Security and Best Practices
    11. Helm Repositories
    12. Packaging and Distribution
    13. Troubleshooting and Debugging
    14. Advanced Topics
    15. Real-World Examples

    1. Introduction to Helm

    What is Helm?

    Helm is the package manager for Kubernetes, often referred to as “the package manager for Kubernetes.” It helps you manage Kubernetes applications through Helm Charts, which are packages of pre-configured Kubernetes resources.

    graph TB
        A[Developer] --> B[Helm CLI]
        B --> C[Helm Chart]
        C --> D[Kubernetes Cluster]
        D --> E[Running Application]
    
        subgraph "Helm Chart"
            F[Templates]
            G[Values]
            H[Chart.yaml]
            I[Dependencies]
        end
    
        C --> F
        C --> G
        C --> H
        C --> I

    Why Use Helm?

    1. Package Management: Bundle related Kubernetes resources
    2. Templating: Reuse configurations across environments
    3. Versioning: Track application releases
    4. Rollback: Easy rollback to previous versions
    5. Dependency Management: Handle complex application dependencies

    Helm vs. Traditional Kubernetes Deployments

    graph LR
        subgraph "Traditional Approach"
            A1[YAML Files] --> A2[kubectl apply] --> A3[K8s Resources]
        end
    
        subgraph "Helm Approach"
            B1[Helm Chart] --> B2[helm install] --> B3[Release] --> B4[K8s Resources]
        end
    
        style B1 fill:#e1f5fe
        style B2 fill:#e8f5e8
        style B3 fill:#fff3e0

    2. Getting Started

    Installation

    From Script Installation

    # installer script that will automatically grab the latest version of Helm and install it locally
    curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
    chmod 700 get_helm.sh
    ./get_helm.sh
    Bash

    Verify Installation

    helm version
    Bash

    Your First Helm Chart

    Let’s create a simple chart:

    helm create my-first-app
    Bash

    This creates the following structure:

    graph TD
        A[my-first-app/] --> B[Chart.yaml]
        A --> C[values.yaml]
        A --> D[templates/]
        A --> E[charts/]
        A --> F[.helmignore]
    
        D --> G[deployment.yaml]
        D --> H[service.yaml]
        D --> I[ingress.yaml]
        D --> J[_helpers.tpl]
        D --> K[NOTES.txt]

    Basic Helm Workflow

    sequenceDiagram
        participant Dev as Developer
        participant Helm as Helm CLI
        participant K8s as Kubernetes
    
        Dev->>Helm: helm create mychart
        Dev->>Helm: helm install myapp ./mychart
        Helm->>K8s: Deploy resources
        K8s-->>Helm: Deployment status
        Helm-->>Dev: Release created
    
        Dev->>Helm: helm upgrade myapp ./mychart
        Helm->>K8s: Update resources
        K8s-->>Helm: Update status
        Helm-->>Dev: Release upgraded

    3. Understanding Helm Architecture

    Helm 3 Architecture

    graph TB
        subgraph "Client Side"
            A[Helm CLI]
            B[Chart Repository]
            C[Local Charts]
        end
    
        subgraph "Kubernetes Cluster"
            D[API Server]
            E[Releases Storage]
            F[Deployed Resources]
        end
    
        A --> D
        A --> B
        A --> C
        D --> E
        D --> F
    
        style A fill:#e1f5fe
        style D fill:#e8f5e8
        style E fill:#fff3e0

    Key Components

    1. Helm CLI: Command-line interface
    2. Charts: Package format
    3. Releases: Installed instances of charts
    4. Repositories: Chart storage locations

    Helm vs Helm 2

    graph TB
        subgraph "Helm 2"
            A2[Helm Client] --> B2[Tiller Server]
            B2 --> C2[Kubernetes API]
        end
    
        subgraph "Helm 3"
            A3[Helm Client] --> C3[Kubernetes API]
        end
    
        style A3 fill:#e8f5e8
        style C3 fill:#e8f5e8

    4. Charts: The Heart of Helm

    Chart Structure

    # Chart.yaml
    apiVersion: v2
    name: my-app
    description: A Helm chart for my application
    type: application
    version: 0.1.0
    appVersion: "1.0"
    maintainers:
      - name: Your Name
        email: your.email@example.com
    dependencies:
      - name: postgresql
        version: 11.6.6
        repository: https://charts.bitnami.com/bitnami
    YAML

    Chart Types

    graph TD
        A[Chart Types] --> B[Application Charts]
        A --> C[Library Charts]
    
        B --> D[Complete Applications]
        B --> E[Microservices]
    
        C --> F[Shared Templates]
        C --> G[Common Functions]
    
        style B fill:#e1f5fe
        style C fill:#fff3e0

    Chart Versioning

    graph LR
        A[Chart v1.0.0] --> B[Chart v1.1.0]
        B --> C[Chart v2.0.0]
    
        A1[App v1.0] --> A
        A2[App v1.1] --> B
        A3[App v2.0] --> C
    
        style A fill:#e8f5e8
        style B fill:#fff3e0
        style C fill:#ffebee

    5. Templates and Values

    Template Basics

    # templates/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: {{ include "myapp.fullname" . }}
      labels:
        {{- include "myapp.labels" . | nindent 4 }}
    spec:
      replicas: {{ .Values.replicaCount }}
      selector:
        matchLabels:
          {{- include "myapp.selectorLabels" . | nindent 6 }}
      template:
        metadata:
          labels:
            {{- include "myapp.selectorLabels" . | nindent 8 }}
        spec:
          containers:
            - name: {{ .Chart.Name }}
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
              ports:
                - containerPort: {{ .Values.service.port }}
    YAML

    Values File

    # values.yaml
    replicaCount: 3
    
    image:
      repository: nginx
      tag: "1.21"
      pullPolicy: IfNotPresent
    
    service:
      type: ClusterIP
      port: 80
    
    ingress:
      enabled: false
      annotations: {}
      hosts:
        - host: example.local
          paths:
            - path: /
              pathType: Prefix
    
    resources:
      limits:
        cpu: 500m
        memory: 512Mi
      requests:
        cpu: 250m
        memory: 256Mi
    YAML

    Template Functions

    graph TD
        A[Template Functions] --> B[Built-in Functions]
        A --> C[Sprig Functions]
        A --> D[Helm Functions]
    
        B --> E[include, define]
        B --> F[if, with, range]
    
        C --> G[String Functions]
        C --> H[Math Functions]
        C --> I[Date Functions]
    
        D --> J[Chart, Release, Values]
        D --> K[Files, Capabilities]

    Advanced Templating Examples

    # Conditional rendering
    {{- if .Values.ingress.enabled }}
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: {{ include "myapp.fullname" . }}
    {{- end }}
    
    # Loops
    {{- range .Values.ingress.hosts }}
      - host: {{ .host | quote }}
        http:
          paths:
          {{- range .paths }}
            - path: {{ .path }}
              pathType: {{ .pathType }}
          {{- end }}
    {{- end }}
    
    # Default values
    image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
    YAML

    6. Helm Commands and CLI

    Essential Commands

    # Chart management
    helm create mychart              # Create new chart
    helm package mychart             # Package chart
    helm lint mychart               # Validate chart
    
    # Repository management
    helm repo add bitnami https://charts.bitnami.com/bitnami
    helm repo update                # Update repository info
    helm repo list                 # List repositories
    helm search repo nginx         # Search for charts
    
    # Release management
    helm install myapp ./mychart    # Install chart
    helm upgrade myapp ./mychart    # Upgrade release
    helm rollback myapp 1          # Rollback to revision 1
    helm uninstall myapp           # Uninstall release
    
    # Release information
    helm list                      # List releases
    helm status myapp             # Show release status
    helm history myapp            # Show release history
    helm get values myapp         # Get release values
    Bash

    Command Workflow

    graph TD
        A[helm create] --> B[Edit Chart]
        B --> C[helm lint]
        C --> D{Lint OK?}
        D -->|No| B
        D -->|Yes| E[helm install]
        E --> F[helm status]
        F --> G[helm upgrade]
        G --> H{Upgrade OK?}
        H -->|No| I[helm rollback]
        H -->|Yes| J[Application Running]
        I --> F

    Debug and Dry Run

    # Dry run - see what would be installed
    helm install myapp ./mychart --dry-run --debug
    
    # Template rendering
    helm template myapp ./mychart
    
    # Test release
    helm test myapp
    Bash

    7. Managing Dependencies

    Chart Dependencies

    # Chart.yaml
    dependencies:
      - name: postgresql
        version: "11.6.6"
        repository: "https://charts.bitnami.com/bitnami"
        condition: postgresql.enabled
      - name: redis
        version: "16.9.11"
        repository: "https://charts.bitnami.com/bitnami"
        condition: redis.enabled
    YAML

    Dependency Management Commands

    # Update dependencies
    helm dependency update
    
    # Download dependencies
    helm dependency build
    
    # List dependencies
    helm dependency list
    Bash

    Dependency Resolution Flow

    graph TD
        A[Chart.yaml] --> B[helm dependency update]
        B --> C[Download Dependencies]
        C --> D[charts/ Directory]
        D --> E[Chart.lock]
    
        F[values.yaml] --> G{Condition Check}
        G -->|True| H[Include Dependency]
        G -->|False| I[Skip Dependency]
    
        style C fill:#e8f5e8
        style E fill:#fff3e0

    Conditional Dependencies

    # values.yaml
    postgresql:
      enabled: true
      auth:
        postgresPassword: "mypassword"
    
    redis:
      enabled: false
    YAML

    8. Advanced Templating

    Named Templates

    # templates/_helpers.tpl
    {{/*
    Expand the name of the chart.
    */}}
    {{- define "myapp.name" -}}
    {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
    {{- end }}
    
    {{/*
    Create a default fully qualified app name.
    */}}
    {{- define "myapp.fullname" -}}
    {{- if .Values.fullnameOverride }}
    {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
    {{- else }}
    {{- $name := default .Chart.Name .Values.nameOverride }}
    {{- if contains $name .Release.Name }}
    {{- .Release.Name | trunc 63 | trimSuffix "-" }}
    {{- else }}
    {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
    {{- end }}
    {{- end }}
    {{- end }}
    YAML

    Flow Control

    # Complex conditionals
    {{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: {{ include "myapp.fullname" . }}
    spec:
      accessModes:
        {{- range .Values.persistence.accessModes }}
        - {{ . | quote }}
        {{- end }}
      resources:
        requests:
          storage: {{ .Values.persistence.size | quote }}
    {{- end }}
    YAML

    Template Organization

    graph TD
        A[templates/] --> B[_helpers.tpl]
        A --> C[deployment.yaml]
        A --> D[service.yaml]
        A --> E[configmap.yaml]
        A --> F[secret.yaml]
        A --> G[ingress.yaml]
        A --> H[tests/]
    
        H --> I[test-connection.yaml]
    
        style B fill:#fff3e0
        style H fill:#e1f5fe

    9. Hooks and Tests

    Helm Hooks

    # Pre-install hook
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: "{{ include "myapp.fullname" . }}-pre-install"
      annotations:
        "helm.sh/hook": pre-install
        "helm.sh/hook-weight": "-5"
        "helm.sh/hook-delete-policy": hook-succeeded
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: pre-install-job
            image: busybox
            command: ['sh', '-c', 'echo Pre-install hook executed']
    YAML

    Hook Types and Lifecycle

    graph TD
        A[Helm Install] --> B[pre-install]
        B --> C[Install Resources]
        C --> D[post-install]
    
        E[Helm Upgrade] --> F[pre-upgrade]
        F --> G[Upgrade Resources]
        G --> H[post-upgrade]
    
        I[Helm Delete] --> J[pre-delete]
        J --> K[Delete Resources]
        K --> L[post-delete]
    
        style B fill:#e8f5e8
        style D fill:#e8f5e8
        style F fill:#fff3e0
        style H fill:#fff3e0

    Test Pods

    # templates/tests/test-connection.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: "{{ include "myapp.fullname" . }}-test"
      annotations:
        "helm.sh/hook": test
    spec:
      restartPolicy: Never
      containers:
        - name: wget
          image: busybox
          command: ['wget']
          args: ['{{ include "myapp.fullname" . }}:{{ .Values.service.port }}']
    YAML

    Running Tests

    # Run tests
    helm test myapp
    
    # Test with logs
    helm test myapp --logs
    Bash

    10. Security and Best Practices

    Security Considerations

    graph TD
        A[Security Best Practices] --> B[RBAC]
        A --> C[Secrets Management]
        A --> D[Image Security]
        A --> E[Network Policies]
    
        B --> F[Service Accounts]
        B --> G[Roles & Bindings]
    
        C --> H[External Secrets]
        C --> I[Sealed Secrets]
    
        D --> J[Image Scanning]
        D --> K[Signed Images]
    
        style A fill:#ffebee
        style B fill:#e8f5e8
        style C fill:#fff3e0

    RBAC Configuration

    # templates/rbac.yaml
    {{- if .Values.rbac.create }}
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: {{ include "myapp.fullname" . }}
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list", "watch"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: {{ include "myapp.fullname" . }}
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: {{ include "myapp.fullname" . }}
    subjects:
    - kind: ServiceAccount
      name: {{ include "myapp.serviceAccountName" . }}
    {{- end }}
    YAML

    Secrets Management

    # Using external secrets
    apiVersion: external-secrets.io/v1beta1
    kind: SecretStore
    metadata:
      name: vault-backend
    spec:
      provider:
        vault:
          server: "https://vault.example.com"
          path: "secret"
          version: "v2"
          auth:
            kubernetes:
              mountPath: "kubernetes"
              role: "myapp"
    YAML

    Chart Best Practices

    1. Use semantic versioning
    2. Include resource limits
    3. Implement health checks
    4. Use meaningful labels
    5. Document configuration options
    # Good practices example
    resources:
      limits:
        cpu: {{ .Values.resources.limits.cpu }}
        memory: {{ .Values.resources.limits.memory }}
      requests:
        cpu: {{ .Values.resources.requests.cpu }}
        memory: {{ .Values.resources.requests.memory }}
    
    livenessProbe:
      httpGet:
        path: /health
        port: http
      initialDelaySeconds: 30
      periodSeconds: 10
    
    readinessProbe:
      httpGet:
        path: /ready
        port: http
      initialDelaySeconds: 5
      periodSeconds: 5
    YAML

    11. Helm Repositories

    Repository Types

    graph TD
        A[Helm Repositories] --> B[Public Repositories]
        A --> C[Private Repositories]
        A --> D[OCI Registries]
    
        B --> E[Bitnami]
        B --> F[Stable]
        B --> G[Jetstack]
    
        C --> H[Harbor]
        C --> I[Artifactory]
        C --> J[ChartMuseum]
    
        D --> K[AWS ECR]
        D --> L[Azure ACR]
        D --> M[Google GCR]

    Managing Repositories

    # Add repositories
    helm repo add bitnami https://charts.bitnami.com/bitnami
    helm repo add jetstack https://charts.jetstack.io
    
    # List repositories
    helm repo list
    
    # Update repository index
    helm repo update
    
    # Search for charts
    helm search repo nginx
    helm search hub wordpress
    
    # Remove repository
    helm repo remove bitnami
    Bash

    Creating a Repository

    # Create repository index
    helm repo index ./charts --url https://myrepo.example.com
    
    # Repository structure
    charts/
    ├── index.yaml
    ├── myapp-1.0.0.tgz
    ├── myapp-1.1.0.tgz
    └── otherapp-2.0.0.tgz
    Bash

    OCI Support

    # Push to OCI registry
    helm push myapp-1.0.0.tgz oci://registry.example.com/helm
    
    # Install from OCI
    helm install myapp oci://registry.example.com/helm/myapp --version 1.0.0
    Bash

    12. Packaging and Distribution

    Chart Packaging

    # Package a chart
    helm package ./mychart
    
    # Package with specific version
    helm package ./mychart --version 1.2.3
    
    # Package and sign
    helm package ./mychart --sign --key mykey --keyring ~/.gnupg/secring.gpg
    Bash

    Chart Verification

    # Verify a chart
    helm verify mychart-1.0.0.tgz
    
    # Install with verification
    helm install myapp ./mychart --verify
    Bash

    Distribution Workflow

    graph TD
        A[Develop Chart] --> B[helm lint]
        B --> C[helm package]
        C --> D[helm push to repo]
        D --> E[Update repo index]
        E --> F[Distribute]
    
        G[Consumer] --> H[helm repo add]
        H --> I[helm repo update]
        I --> J[helm install]
    
        style C fill:#e8f5e8
        style D fill:#fff3e0
        style J fill:#e1f5fe

    Chart Metadata

    # Chart.yaml - Complete example
    apiVersion: v2
    name: myapp
    description: A comprehensive web application
    type: application
    version: 1.2.3
    appVersion: "2.1.0"
    kubeVersion: ">=1.19.0"
    deprecated: false
    keywords:
      - web
      - application
      - microservice
    home: https://github.com/myorg/myapp
    sources:
      - https://github.com/myorg/myapp
    maintainers:
      - name: John Doe
        email: john@example.com
        url: https://github.com/johndoe
    icon: https://example.com/icon.png
    annotations:
      category: Application
      licenses: Apache-2.0
    YAML

    13. Troubleshooting and Debugging

    Common Issues and Solutions

    graph TD
        A[Common Issues] --> B[Template Errors]
        A --> C[Value Problems]
        A --> D[Dependency Issues]
        A --> E[Resource Conflicts]
    
        B --> F[Syntax Errors]
        B --> G[Missing Functions]
    
        C --> H[Type Mismatches]
        C --> I[Missing Values]
    
        D --> J[Version Conflicts]
        D --> K[Repository Issues]
    
        E --> L[Name Conflicts]
        E --> M[RBAC Issues]

    Debugging Commands

    # Debug template rendering
    helm template myapp ./mychart --debug
    
    # Dry run with debug
    helm install myapp ./mychart --dry-run --debug
    
    # Get rendered manifests
    helm get manifest myapp
    
    # Show all release information
    helm get all myapp
    
    # Check release history
    helm history myapp
    Bash

    Template Debugging

    # Debug template with values
    {{- if .Values.debug }}
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: debug-{{ include "myapp.fullname" . }}
    data:
      values.yaml: |
    {{ .Values | toYaml | indent 4 }}
      chart-info: |
        Chart: {{ .Chart.Name }}-{{ .Chart.Version }}
        Release: {{ .Release.Name }}
        Namespace: {{ .Release.Namespace }}
    {{- end }}
    YAML

    Validation and Testing

    # Lint chart
    helm lint ./mychart
    
    # Validate against Kubernetes
    helm template ./mychart | kubectl apply --dry-run=client -f -
    
    # Test installation
    helm install test-release ./mychart --wait --timeout 5m
    helm test test-release
    helm uninstall test-release
    Bash

    14. Advanced Topics

    Helm Plugins

    # Install plugins
    helm plugin install https://github.com/databus23/helm-diff
    
    # List installed plugins
    helm plugin list
    
    # Use plugin
    helm diff upgrade myapp ./mychart
    Bash

    Custom Resource Definitions (CRDs)

    # templates/crds/mycrd.yaml
    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: myresources.example.com
      annotations:
        "helm.sh/hook": crd-install
        "helm.sh/hook-weight": "-1"
    spec:
      group: example.com
      versions:
      - name: v1
        served: true
        storage: true
        schema:
          openAPIV3Schema:
            type: object
            properties:
              spec:
                type: object
                properties:
                  replicas:
                    type: integer
      scope: Namespaced
      names:
        plural: myresources
        singular: myresource
        kind: MyResource
    YAML

    Multi-Environment Deployments

    graph TD
        A[Base Chart] --> B[Development]
        A --> C[Staging]
        A --> D[Production]
    
        B --> E[dev-values.yaml]
        C --> F[staging-values.yaml]
        D --> G[prod-values.yaml]
    
        style E fill:#e8f5e8
        style F fill:#fff3e0
        style G fill:#ffebee
    # Environment-specific deployments
    helm install myapp-dev ./mychart -f values-dev.yaml
    helm install myapp-staging ./mychart -f values-staging.yaml
    helm install myapp-prod ./mychart -f values-prod.yaml
    Bash

    Helm Operators

    # HelmRelease CRD for Flux
    apiVersion: helm.toolkit.fluxcd.io/v2beta1
    kind: HelmRelease
    metadata:
      name: myapp
      namespace: default
    spec:
      interval: 5m
      chart:
        spec:
          chart: myapp
          version: "1.0.0"
          sourceRef:
            kind: HelmRepository
            name: myrepo
      values:
        replicaCount: 3
        image:
          tag: "latest"
    YAML

    15. Real-World Examples

    Complete Microservice Chart

    # Chart.yaml
    apiVersion: v2
    name: microservice
    description: Production-ready microservice chart
    version: 1.0.0
    appVersion: "1.0.0"
    dependencies:
      - name: postgresql
        version: "11.6.6"
        repository: "https://charts.bitnami.com/bitnami"
        condition: postgresql.enabled
      - name: redis
        version: "16.9.11" 
        repository: "https://charts.bitnami.com/bitnami"
        condition: redis.enabled
    YAML
    # values.yaml
    replicaCount: 3
    
    image:
      repository: myapp
      tag: "1.0.0"
      pullPolicy: IfNotPresent
    
    service:
      type: ClusterIP
      port: 8080
      targetPort: 8080
    
    ingress:
      enabled: true
      className: nginx
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt-prod
      hosts:
        - host: myapp.example.com
          paths:
            - path: /
              pathType: Prefix
      tls:
        - secretName: myapp-tls
          hosts:
            - myapp.example.com
    
    autoscaling:
      enabled: true
      minReplicas: 3
      maxReplicas: 10
      targetCPUUtilizationPercentage: 70
      targetMemoryUtilizationPercentage: 80
    
    resources:
      limits:
        cpu: 500m
        memory: 512Mi
      requests:
        cpu: 250m
        memory: 256Mi
    
    postgresql:
      enabled: true
      auth:
        postgresPassword: "mypassword"
        database: "myapp"
    
    redis:
      enabled: true
      auth:
        enabled: false
    
    monitoring:
      enabled: true
      serviceMonitor:
        enabled: true
    YAML

    Complex Deployment Template

    # templates/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: {{ include "microservice.fullname" . }}
      labels:
        {{- include "microservice.labels" . | nindent 4 }}
    spec:
      {{- if not .Values.autoscaling.enabled }}
      replicas: {{ .Values.replicaCount }}
      {{- end }}
      selector:
        matchLabels:
          {{- include "microservice.selectorLabels" . | nindent 6 }}
      template:
        metadata:
          annotations:
            checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
            {{- with .Values.podAnnotations }}
            {{- toYaml . | nindent 8 }}
            {{- end }}
          labels:
            {{- include "microservice.selectorLabels" . | nindent 8 }}
        spec:
          {{- with .Values.imagePullSecrets }}
          imagePullSecrets:
            {{- toYaml . | nindent 8 }}
          {{- end }}
          serviceAccountName: {{ include "microservice.serviceAccountName" . }}
          securityContext:
            {{- toYaml .Values.podSecurityContext | nindent 8 }}
          containers:
            - name: {{ .Chart.Name }}
              securityContext:
                {{- toYaml .Values.securityContext | nindent 12 }}
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
              imagePullPolicy: {{ .Values.image.pullPolicy }}
              ports:
                - name: http
                  containerPort: {{ .Values.service.targetPort }}
                  protocol: TCP
              livenessProbe:
                httpGet:
                  path: /health
                  port: http
                initialDelaySeconds: 30
                periodSeconds: 10
              readinessProbe:
                httpGet:
                  path: /ready
                  port: http
                initialDelaySeconds: 5
                periodSeconds: 5
              resources:
                {{- toYaml .Values.resources | nindent 12 }}
              env:
                - name: DATABASE_URL
                  valueFrom:
                    secretKeyRef:
                      name: {{ include "microservice.fullname" . }}-db
                      key: url
                {{- if .Values.redis.enabled }}
                - name: REDIS_URL
                  value: "{{ include "microservice.fullname" . }}-redis-master:6379"
                {{- end }}
              envFrom:
                - configMapRef:
                    name: {{ include "microservice.fullname" . }}
          {{- with .Values.nodeSelector }}
          nodeSelector:
            {{- toYaml . | nindent 8 }}
          {{- end }}
          {{- with .Values.affinity }}
          affinity:
            {{- toYaml . | nindent 8 }}
          {{- end }}
          {{- with .Values.tolerations }}
          tolerations:
            {{- toYaml . | nindent 8 }}
          {{- end }}
    YAML

    CI/CD Integration

    # .github/workflows/helm.yml
    name: Helm Chart CI/CD
    
    on:
      push:
        branches: [main]
      pull_request:
        branches: [main]
    
    jobs:
      lint-test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
            with:
              fetch-depth: 0
    
          - name: Set up Helm
            uses: azure/setup-helm@v3
            with:
              version: v3.12.0
    
          - name: Set up chart-testing
            uses: helm/chart-testing-action@v2.4.0
    
          - name: Run chart-testing (list)
            id: list
            run: |
              changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }})
              if [[ -n "$changed" ]]; then
                echo "changed=true" >> $GITHUB_OUTPUT
              fi
    
          - name: Run chart-testing (lint)
            run: ct lint --target-branch ${{ github.event.repository.default_branch }}
    
          - name: Create kind cluster
            uses: helm/kind-action@v1.4.0
            if: steps.list.outputs.changed == 'true'
    
          - name: Run chart-testing (install)
            run: ct install --target-branch ${{ github.event.repository.default_branch }}
    YAML

    Conclusion

    This comprehensive guide covers Helm from basic concepts to advanced enterprise usage. Key takeaways:

    1. Start Simple: Begin with basic charts and gradually add complexity
    2. Follow Best Practices: Use proper templating, security measures, and documentation
    3. Test Thoroughly: Implement proper testing and validation workflows
    4. Automate: Integrate Helm into your CI/CD pipelines
    5. Stay Secure: Implement proper RBAC, secrets management, and security scanning

    Next Steps

    1. Practice with the examples provided
    2. Explore the official Helm documentation
    3. Join the Helm community
    4. Contribute to open-source charts
    5. Implement Helm in your organization’s workflows

    Remember: Helm is a powerful tool that becomes more valuable as you understand Kubernetes better. Keep learning and practicing!


    Additional Resources


    This guide represents current best practices as of 2025. Always refer to the latest official documentation for the most up-to-date information.


    Discover more from Altgr Blog

    Subscribe to get the latest posts sent to your email.

    Leave a Reply

    Your email address will not be published. Required fields are marked *