Claude Cursor Skill

helm-chart-scaffolding

Design, organize, and manage Helm charts for templating and packaging Kubernetes applications with reusable configurations. Use when creating Helm charts, packaging Kubernetes applications, or implementing templated deployments.

LLM Mart · 0 points · 13 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download wshobson-agents-plugins_kubernetes-operations_skills_helm-chart-scaffolding-554237f.zip · 12 KB
Part of wshobson/agents — 170 skills

Install

skills CLI npx skills add https://github.com/wshobson/agents/tree/main/plugins/kubernetes-operations/skills/helm-chart-scaffolding
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install wshobson-agents@llmmart
Git git clone https://github.com/wshobson/agents.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole wshobson/agents collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Helm Chart Scaffolding

Comprehensive guidance for creating, organizing, and managing Helm charts for packaging and deploying Kubernetes applications.

Purpose

This skill provides step-by-step instructions for building production-ready Helm charts, including chart structure, templating patterns, values management, and validation strategies.

When to Use This Skill

Use this skill when you need to:

  • Create new Helm charts from scratch
  • Package Kubernetes applications for distribution
  • Manage multi-environment deployments with Helm
  • Implement templating for reusable Kubernetes manifests
  • Set up Helm chart repositories
  • Follow Helm best practices and conventions

Detailed patterns and worked examples

Detailed pattern documentation lives in references/details.md. Read that file when the navigation tier above is insufficient.

Best Practices

  1. Use semantic versioning for chart and app versions
  2. Document all values in values.yaml with comments
  3. Use template helpers for repeated logic
  4. Validate charts before packaging
  5. Pin dependency versions explicitly
  6. Use conditions for optional resources
  7. Follow naming conventions (lowercase, hyphens)
  8. Include NOTES.txt with usage instructions
  9. Add labels consistently using helpers
  10. Test installations in all environments

Troubleshooting

Template rendering errors:

helm template my-app ./my-app --debug

Dependency issues:

helm dependency update
helm dependency list

Installation failures:

helm install my-app ./my-app --dry-run --debug
kubectl get events --sort-by='.lastTimestamp'

Related Skills

  • k8s-manifest-generator - For creating base Kubernetes manifests
  • gitops-workflow - For automated Helm chart deployments
Files (agents)
  • assets
    • Chart.yaml.template 801 B · in bundle
    • values.yaml.template 3.1 KB · in bundle
  • references
    • chart-structure.md 11.2 KB
      # Helm Chart Structure Reference
      
      Complete guide to Helm chart organization, file conventions, and best practices.
      
      ## Standard Chart Directory Structure
      
      ```
      my-app/
      ├── Chart.yaml              # Chart metadata (required)
      ├── Chart.lock              # Dependency lock file (generated)
      ├── values.yaml             # Default configuration values (required)
      ├── values.schema.json      # JSON schema for values validation
      ├── .helmignore             # Patterns to ignore when packaging
      ├── README.md               # Chart documentation
      ├── LICENSE                 # Chart license
      ├── charts/                 # Chart dependencies (bundled)
      │   └── postgresql-12.0.0.tgz
      ├── crds/                   # Custom Resource Definitions
      │   └── my-crd.yaml
      ├── templates/              # Kubernetes manifest templates (required)
      │   ├── NOTES.txt          # Post-install instructions
      │   ├── _helpers.tpl       # Template helper functions
      │   ├── deployment.yaml
      │   ├── service.yaml
      │   ├── ingress.yaml
      │   ├── configmap.yaml
      │   ├── secret.yaml
      │   ├── serviceaccount.yaml
      │   ├── hpa.yaml
      │   ├── pdb.yaml
      │   ├── networkpolicy.yaml
      │   └── tests/
      │       └── test-connection.yaml
      └── files/                  # Additional files to include
          └── config/
              └── app.conf
      ```
      
      ## Chart.yaml Specification
      
      ### API Version v2 (Helm 3+)
      
      ```yaml
      apiVersion: v2 # Required: API version
      name: my-application # Required: Chart name
      version: 1.2.3 # Required: Chart version (SemVer)
      appVersion: "2.5.0" # Application version
      description: A Helm chart for my application # Required
      type: application # Chart type: application or library
      keywords: # Search keywords
        - web
        - api
        - backend
      home: https://example.com # Project home page
      sources: # Source code URLs
        - https://github.com/example/my-app
      maintainers: # Maintainer list
        - name: John Doe
          email: john@example.com
          url: https://github.com/johndoe
      icon: https://example.com/icon.png # Chart icon URL
      kubeVersion: ">=1.24.0" # Compatible Kubernetes versions
      deprecated: false # Mark chart as deprecated
      annotations: # Arbitrary annotations
        example.com/release-notes: https://example.com/releases/v1.2.3
      dependencies: # Chart dependencies
        - name: postgresql
          version: "12.0.0"
          repository: "https://charts.bitnami.com/bitnami"
          condition: postgresql.enabled
          tags:
            - database
          import-values:
            - child: database
              parent: database
          alias: db
      ```
      
      ## Chart Types
      
      ### Application Chart
      
      ```yaml
      type: application
      ```
      
      - Standard Kubernetes applications
      - Can be installed and managed
      - Contains templates for K8s resources
      
      ### Library Chart
      
      ```yaml
      type: library
      ```
      
      - Shared template helpers
      - Cannot be installed directly
      - Used as dependency by other charts
      - No templates/ directory
      
      ## Values Files Organization
      
      ### values.yaml (defaults)
      
      ```yaml
      # Global values (shared with subcharts)
      global:
        imageRegistry: docker.io
        imagePullSecrets: []
      
      # Image configuration
      image:
        registry: docker.io
        repository: myapp/web
        tag: "" # Defaults to .Chart.AppVersion
        pullPolicy: IfNotPresent
      
      # Deployment settings
      replicaCount: 1
      revisionHistoryLimit: 10
      
      # Pod configuration
      podAnnotations: {}
      podSecurityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
      
      # Container security
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
      
      # Service
      service:
        type: ClusterIP
        port: 80
        targetPort: http
        annotations: {}
      
      # Resources
      resources:
        limits:
          cpu: 100m
          memory: 128Mi
        requests:
          cpu: 100m
          memory: 128Mi
      
      # Autoscaling
      autoscaling:
        enabled: false
        minReplicas: 1
        maxReplicas: 100
        targetCPUUtilizationPercentage: 80
      
      # Node selection
      nodeSelector: {}
      tolerations: []
      affinity: {}
      
      # Monitoring
      serviceMonitor:
        enabled: false
        interval: 30s
      ```
      
      ### values.schema.json (validation)
      
      ```json
      {
        "$schema": "https://json-schema.org/draft-07/schema#",
        "type": "object",
        "properties": {
          "replicaCount": {
            "type": "integer",
            "minimum": 1
          },
          "image": {
            "type": "object",
            "required": ["repository"],
            "properties": {
              "repository": {
                "type": "string"
              },
              "tag": {
                "type": "string"
              },
              "pullPolicy": {
                "type": "string",
                "enum": ["Always", "IfNotPresent", "Never"]
              }
            }
          }
        },
        "required": ["image"]
      }
      ```
      
      ## Template Files
      
      ### Template Naming Conventions
      
      - **Lowercase with hyphens**: `deployment.yaml`, `service-account.yaml`
      - **Partial templates**: Prefix with underscore `_helpers.tpl`
      - **Tests**: Place in `templates/tests/`
      - **CRDs**: Place in `crds/` (not templated)
      
      ### Common Templates
      
      #### \_helpers.tpl
      
      ```yaml
      {{/*
      Standard naming helpers
      */}}
      {{- define "my-app.name" -}}
      {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
      {{- end -}}
      
      {{- define "my-app.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 -}}
      
      {{- define "my-app.chart" -}}
      {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
      {{- end -}}
      
      {{/*
      Common labels
      */}}
      {{- define "my-app.labels" -}}
      helm.sh/chart: {{ include "my-app.chart" . }}
      {{ include "my-app.selectorLabels" . }}
      {{- if .Chart.AppVersion }}
      app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
      {{- end }}
      app.kubernetes.io/managed-by: {{ .Release.Service }}
      {{- end -}}
      
      {{- define "my-app.selectorLabels" -}}
      app.kubernetes.io/name: {{ include "my-app.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
      {{- end -}}
      
      {{/*
      Image name helper
      */}}
      {{- define "my-app.image" -}}
      {{- $registry := .Values.global.imageRegistry | default .Values.image.registry -}}
      {{- $repository := .Values.image.repository -}}
      {{- $tag := .Values.image.tag | default .Chart.AppVersion -}}
      {{- printf "%s/%s:%s" $registry $repository $tag -}}
      {{- end -}}
      ```
      
      #### NOTES.txt
      
      ```
      Thank you for installing {{ .Chart.Name }}.
      
      Your release is named {{ .Release.Name }}.
      
      To learn more about the release, try:
      
        $ helm status {{ .Release.Name }}
        $ helm get all {{ .Release.Name }}
      
      {{- if .Values.ingress.enabled }}
      
      Application URL:
      {{- range .Values.ingress.hosts }}
        http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .host }}{{ .path }}
      {{- end }}
      {{- else }}
      
      Get the application URL by running:
        export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "my-app.name" . }}" -o jsonpath="{.items[0].metadata.name}")
        kubectl port-forward $POD_NAME 8080:80
        echo "Visit http://127.0.0.1:8080"
      {{- end }}
      ```
      
      ## Dependencies Management
      
      ### Declaring Dependencies
      
      ```yaml
      # Chart.yaml
      dependencies:
        - name: postgresql
          version: "12.0.0"
          repository: "https://charts.bitnami.com/bitnami"
          condition: postgresql.enabled # Enable/disable via values
          tags: # Group dependencies
            - database
          import-values: # Import values from subchart
            - child: database
              parent: database
          alias: db # Reference as .Values.db
      ```
      
      ### Managing Dependencies
      
      ```bash
      # Update dependencies
      helm dependency update
      
      # List dependencies
      helm dependency list
      
      # Build dependencies
      helm dependency build
      ```
      
      ### Chart.lock
      
      Generated automatically by `helm dependency update`:
      
      ```yaml
      dependencies:
        - name: postgresql
          repository: https://charts.bitnami.com/bitnami
          version: 12.0.0
      digest: sha256:abcd1234...
      generated: "2024-01-01T00:00:00Z"
      ```
      
      ## .helmignore
      
      Exclude files from chart package:
      
      ```
      # Development files
      .git/
      .gitignore
      *.md
      docs/
      
      # Build artifacts
      *.swp
      *.bak
      *.tmp
      *.orig
      
      # CI/CD
      .travis.yml
      .gitlab-ci.yml
      Jenkinsfile
      
      # Testing
      test/
      *.test
      
      # IDE
      .vscode/
      .idea/
      *.iml
      ```
      
      ## Custom Resource Definitions (CRDs)
      
      Place CRDs in `crds/` directory:
      
      ```
      crds/
      ├── my-app-crd.yaml
      └── another-crd.yaml
      ```
      
      **Important CRD notes:**
      
      - CRDs are installed before any templates
      - CRDs are NOT templated (no `{{ }}` syntax)
      - CRDs are NOT upgraded or deleted with chart
      - Use `helm install --skip-crds` to skip installation
      
      ## Chart Versioning
      
      ### Semantic Versioning
      
      - **Chart Version**: Increment when chart changes
        - MAJOR: Breaking changes
        - MINOR: New features, backward compatible
        - PATCH: Bug fixes
      
      - **App Version**: Application version being deployed
        - Can be any string
        - Not required to follow SemVer
      
      ```yaml
      version: 2.3.1 # Chart version
      appVersion: "1.5.0" # Application version
      ```
      
      ## Chart Testing
      
      ### Test Files
      
      ```yaml
      # templates/tests/test-connection.yaml
      apiVersion: v1
      kind: Pod
      metadata:
        name: "{{ include "my-app.fullname" . }}-test-connection"
        annotations:
          "helm.sh/hook": test
          "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
      spec:
        containers:
        - name: wget
          image: busybox
          command: ['wget']
          args: ['{{ include "my-app.fullname" . }}:{{ .Values.service.port }}']
        restartPolicy: Never
      ```
      
      ### Running Tests
      
      ```bash
      helm test my-release
      helm test my-release --logs
      ```
      
      ## Hooks
      
      Helm hooks allow intervention at specific points:
      
      ```yaml
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: {{ include "my-app.fullname" . }}-migration
        annotations:
          "helm.sh/hook": pre-upgrade,pre-install
          "helm.sh/hook-weight": "-5"
          "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
      ```
      
      ### Hook Types
      
      - `pre-install`: Before templates rendered
      - `post-install`: After all resources loaded
      - `pre-delete`: Before any resources deleted
      - `post-delete`: After all resources deleted
      - `pre-upgrade`: Before upgrade
      - `post-upgrade`: After upgrade
      - `pre-rollback`: Before rollback
      - `post-rollback`: After rollback
      - `test`: Run with `helm test`
      
      ### Hook Weight
      
      Controls hook execution order (-5 to 5, lower runs first)
      
      ### Hook Deletion Policies
      
      - `before-hook-creation`: Delete previous hook before new one
      - `hook-succeeded`: Delete after successful execution
      - `hook-failed`: Delete if hook fails
      
      ## Best Practices
      
      1. **Use helpers** for repeated template logic
      2. **Quote strings** in templates: `{{ .Values.name | quote }}`
      3. **Validate values** with values.schema.json
      4. **Document all values** in values.yaml
      5. **Use semantic versioning** for chart versions
      6. **Pin dependency versions** exactly
      7. **Include NOTES.txt** with usage instructions
      8. **Add tests** for critical functionality
      9. **Use hooks** for database migrations
      10. **Keep charts focused** - one application per chart
      
      ## Chart Repository Structure
      
      ```
      helm-charts/
      ├── index.yaml
      ├── my-app-1.0.0.tgz
      ├── my-app-1.1.0.tgz
      ├── my-app-1.2.0.tgz
      └── another-chart-2.0.0.tgz
      ```
      
      ### Creating Repository Index
      
      ```bash
      helm repo index . --url https://charts.example.com
      ```
      
      ## Related Resources
      
      - [Helm Documentation](https://helm.sh/docs/)
      - [Chart Template Guide](https://helm.sh/docs/chart_template_guide/)
      - [Best Practices](https://helm.sh/docs/chart_best_practices/)
      
    • details.md 9.2 KB
      # helm-chart-scaffolding — detailed patterns and worked examples
      
      ## Helm Overview
      
      **Helm** is the package manager for Kubernetes that:
      
      - Templates Kubernetes manifests for reusability
      - Manages application releases and rollbacks
      - Handles dependencies between charts
      - Provides version control for deployments
      - Simplifies configuration management across environments
      
      ## Step-by-Step Workflow
      
      ### 1. Initialize Chart Structure
      
      **Create new chart:**
      
      ```bash
      helm create my-app
      ```
      
      **Standard chart structure:**
      
      ```
      my-app/
      ├── Chart.yaml           # Chart metadata
      ├── values.yaml          # Default configuration values
      ├── charts/              # Chart dependencies
      ├── templates/           # Kubernetes manifest templates
      │   ├── NOTES.txt       # Post-install notes
      │   ├── _helpers.tpl    # Template helpers
      │   ├── deployment.yaml
      │   ├── service.yaml
      │   ├── ingress.yaml
      │   ├── serviceaccount.yaml
      │   ├── hpa.yaml
      │   └── tests/
      │       └── test-connection.yaml
      └── .helmignore         # Files to ignore
      ```
      
      ### 2. Configure Chart.yaml
      
      **Chart metadata defines the package:**
      
      ```yaml
      apiVersion: v2
      name: my-app
      description: A Helm chart for My Application
      type: application
      version: 1.0.0 # Chart version
      appVersion: "2.1.0" # Application version
      
      # Keywords for chart discovery
      keywords:
        - web
        - api
        - backend
      
      # Maintainer information
      maintainers:
        - name: DevOps Team
          email: devops@example.com
          url: https://github.com/example/my-app
      
      # Source code repository
      sources:
        - https://github.com/example/my-app
      
      # Homepage
      home: https://example.com
      
      # Chart icon
      icon: https://example.com/icon.png
      
      # Dependencies
      dependencies:
        - name: postgresql
          version: "12.0.0"
          repository: "https://charts.bitnami.com/bitnami"
          condition: postgresql.enabled
        - name: redis
          version: "17.0.0"
          repository: "https://charts.bitnami.com/bitnami"
          condition: redis.enabled
      ```
      
      **Reference:** See `assets/Chart.yaml.template` for complete example
      
      ### 3. Design values.yaml Structure
      
      **Organize values hierarchically:**
      
      ```yaml
      # Image configuration
      image:
        repository: myapp
        tag: "1.0.0"
        pullPolicy: IfNotPresent
      
      # Number of replicas
      replicaCount: 3
      
      # Service configuration
      service:
        type: ClusterIP
        port: 80
        targetPort: 8080
      
      # Ingress configuration
      ingress:
        enabled: false
        className: nginx
        hosts:
          - host: app.example.com
            paths:
              - path: /
                pathType: Prefix
      
      # Resources
      resources:
        requests:
          memory: "256Mi"
          cpu: "250m"
        limits:
          memory: "512Mi"
          cpu: "500m"
      
      # Autoscaling
      autoscaling:
        enabled: false
        minReplicas: 2
        maxReplicas: 10
        targetCPUUtilizationPercentage: 80
      
      # Environment variables
      env:
        - name: LOG_LEVEL
          value: "info"
      
      # ConfigMap data
      configMap:
        data:
          APP_MODE: production
      
      # Dependencies
      postgresql:
        enabled: true
        auth:
          database: myapp
          username: myapp
      
      redis:
        enabled: false
      ```
      
      **Reference:** See `assets/values.yaml.template` for complete structure
      
      ### 4. Create Template Files
      
      **Use Go templating with Helm functions:**
      
      **templates/deployment.yaml:**
      
      ```yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: {{ include "my-app.fullname" . }}
        labels:
          {{- include "my-app.labels" . | nindent 4 }}
      spec:
        {{- if not .Values.autoscaling.enabled }}
        replicas: {{ .Values.replicaCount }}
        {{- end }}
        selector:
          matchLabels:
            {{- include "my-app.selectorLabels" . | nindent 6 }}
        template:
          metadata:
            labels:
              {{- include "my-app.selectorLabels" . | nindent 8 }}
          spec:
            containers:
            - name: {{ .Chart.Name }}
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
              imagePullPolicy: {{ .Values.image.pullPolicy }}
              ports:
              - name: http
                containerPort: {{ .Values.service.targetPort }}
              resources:
                {{- toYaml .Values.resources | nindent 12 }}
              env:
                {{- toYaml .Values.env | nindent 12 }}
      ```
      
      ### 5. Create Template Helpers
      
      **templates/\_helpers.tpl:**
      
      ```yaml
      {{/*
      Expand the name of the chart.
      */}}
      {{- define "my-app.name" -}}
      {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
      {{- end }}
      
      {{/*
      Create a default fully qualified app name.
      */}}
      {{- define "my-app.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 }}
      
      {{/*
      Common labels
      */}}
      {{- define "my-app.labels" -}}
      helm.sh/chart: {{ include "my-app.chart" . }}
      {{ include "my-app.selectorLabels" . }}
      {{- if .Chart.AppVersion }}
      app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
      {{- end }}
      app.kubernetes.io/managed-by: {{ .Release.Service }}
      {{- end }}
      
      {{/*
      Selector labels
      */}}
      {{- define "my-app.selectorLabels" -}}
      app.kubernetes.io/name: {{ include "my-app.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
      {{- end }}
      ```
      
      ### 6. Manage Dependencies
      
      **Add dependencies in Chart.yaml:**
      
      ```yaml
      dependencies:
        - name: postgresql
          version: "12.0.0"
          repository: "https://charts.bitnami.com/bitnami"
          condition: postgresql.enabled
      ```
      
      **Update dependencies:**
      
      ```bash
      helm dependency update
      helm dependency build
      ```
      
      **Override dependency values:**
      
      ```yaml
      # values.yaml
      postgresql:
        enabled: true
        auth:
          database: myapp
          username: myapp
          password: changeme
        primary:
          persistence:
            enabled: true
            size: 10Gi
      ```
      
      ### 7. Test and Validate
      
      **Validation commands:**
      
      ```bash
      # Lint the chart
      helm lint my-app/
      
      # Dry-run installation
      helm install my-app ./my-app --dry-run --debug
      
      # Template rendering
      helm template my-app ./my-app
      
      # Template with values
      helm template my-app ./my-app -f values-prod.yaml
      
      # Show computed values
      helm show values ./my-app
      ```
      
      **Validation script:**
      
      ```bash
      #!/bin/bash
      set -e
      
      echo "Linting chart..."
      helm lint .
      
      echo "Testing template rendering..."
      helm template test-release . --dry-run
      
      echo "Checking for required values..."
      helm template test-release . --validate
      
      echo "All validations passed!"
      ```
      
      **Reference:** See `scripts/validate-chart.sh`
      
      ### 8. Package and Distribute
      
      **Package the chart:**
      
      ```bash
      helm package my-app/
      # Creates: my-app-1.0.0.tgz
      ```
      
      **Create chart repository:**
      
      ```bash
      # Create index
      helm repo index .
      
      # Upload to repository
      # AWS S3 example
      aws s3 sync . s3://my-helm-charts/ --exclude "*" --include "*.tgz" --include "index.yaml"
      ```
      
      **Use the chart:**
      
      ```bash
      helm repo add my-repo https://charts.example.com
      helm repo update
      helm install my-app my-repo/my-app
      ```
      
      ### 9. Multi-Environment Configuration
      
      **Environment-specific values files:**
      
      ```
      my-app/
      ├── values.yaml          # Defaults
      ├── values-dev.yaml      # Development
      ├── values-staging.yaml  # Staging
      └── values-prod.yaml     # Production
      ```
      
      **values-prod.yaml:**
      
      ```yaml
      replicaCount: 5
      
      image:
        tag: "2.1.0"
      
      resources:
        requests:
          memory: "512Mi"
          cpu: "500m"
        limits:
          memory: "1Gi"
          cpu: "1000m"
      
      autoscaling:
        enabled: true
        minReplicas: 3
        maxReplicas: 20
      
      ingress:
        enabled: true
        hosts:
          - host: app.example.com
            paths:
              - path: /
                pathType: Prefix
      
      postgresql:
        enabled: true
        primary:
          persistence:
            size: 100Gi
      ```
      
      **Install with environment:**
      
      ```bash
      helm install my-app ./my-app -f values-prod.yaml --namespace production
      ```
      
      ### 10. Implement Hooks and Tests
      
      **Pre-install hook:**
      
      ```yaml
      # templates/pre-install-job.yaml
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: {{ include "my-app.fullname" . }}-db-setup
        annotations:
          "helm.sh/hook": pre-install
          "helm.sh/hook-weight": "-5"
          "helm.sh/hook-delete-policy": hook-succeeded
      spec:
        template:
          spec:
            containers:
            - name: db-setup
              image: postgres:15
              command: ["psql", "-c", "CREATE DATABASE myapp"]
            restartPolicy: Never
      ```
      
      **Test connection:**
      
      ```yaml
      # templates/tests/test-connection.yaml
      apiVersion: v1
      kind: Pod
      metadata:
        name: "{{ include "my-app.fullname" . }}-test-connection"
        annotations:
          "helm.sh/hook": test
      spec:
        containers:
        - name: wget
          image: busybox
          command: ['wget']
          args: ['{{ include "my-app.fullname" . }}:{{ .Values.service.port }}']
        restartPolicy: Never
      ```
      
      **Run tests:**
      
      ```bash
      helm test my-app
      ```
      
      ## Common Patterns
      
      ### Pattern 1: Conditional Resources
      
      ```yaml
      {{- if .Values.ingress.enabled }}
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: {{ include "my-app.fullname" . }}
      spec:
        # ...
      {{- end }}
      ```
      
      ### Pattern 2: Iterating Over Lists
      
      ```yaml
      env:
      {{- range .Values.env }}
      - name: {{ .name }}
        value: {{ .value | quote }}
      {{- end }}
      ```
      
      ### Pattern 3: Including Files
      
      ```yaml
      data:
        config.yaml: |
          {{- .Files.Get "config/application.yaml" | nindent 4 }}
      ```
      
      ### Pattern 4: Global Values
      
      ```yaml
      global:
        imageRegistry: docker.io
        imagePullSecrets:
          - name: regcred
      
      # Use in templates:
      image: {{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}
      ```
      
  • scripts
    • validate-chart.sh 6.4 KB
      #!/bin/bash
      set -e
      
      CHART_DIR="${1:-.}"
      RELEASE_NAME="test-release"
      
      echo "═══════════════════════════════════════════════════════"
      echo "  Helm Chart Validation"
      echo "═══════════════════════════════════════════════════════"
      echo ""
      
      # Colors
      GREEN='\033[0;32m'
      YELLOW='\033[1;33m'
      RED='\033[0;31m'
      NC='\033[0m' # No Color
      
      success() {
          echo -e "${GREEN}✓${NC} $1"
      }
      
      warning() {
          echo -e "${YELLOW}⚠${NC} $1"
      }
      
      error() {
          echo -e "${RED}✗${NC} $1"
      }
      
      # Check if Helm is installed
      if ! command -v helm &> /dev/null; then
          error "Helm is not installed"
          exit 1
      fi
      
      echo "📦 Chart directory: $CHART_DIR"
      echo ""
      
      # 1. Check chart structure
      echo "1️⃣  Checking chart structure..."
      if [ ! -f "$CHART_DIR/Chart.yaml" ]; then
          error "Chart.yaml not found"
          exit 1
      fi
      success "Chart.yaml exists"
      
      if [ ! -f "$CHART_DIR/values.yaml" ]; then
          error "values.yaml not found"
          exit 1
      fi
      success "values.yaml exists"
      
      if [ ! -d "$CHART_DIR/templates" ]; then
          error "templates/ directory not found"
          exit 1
      fi
      success "templates/ directory exists"
      echo ""
      
      # 2. Lint the chart
      echo "2️⃣  Linting chart..."
      if helm lint "$CHART_DIR"; then
          success "Chart passed lint"
      else
          error "Chart failed lint"
          exit 1
      fi
      echo ""
      
      # 3. Check Chart.yaml
      echo "3️⃣  Validating Chart.yaml..."
      CHART_NAME=$(grep "^name:" "$CHART_DIR/Chart.yaml" | awk '{print $2}')
      CHART_VERSION=$(grep "^version:" "$CHART_DIR/Chart.yaml" | awk '{print $2}')
      APP_VERSION=$(grep "^appVersion:" "$CHART_DIR/Chart.yaml" | awk '{print $2}' | tr -d '"')
      
      if [ -z "$CHART_NAME" ]; then
          error "Chart name not found"
          exit 1
      fi
      success "Chart name: $CHART_NAME"
      
      if [ -z "$CHART_VERSION" ]; then
          error "Chart version not found"
          exit 1
      fi
      success "Chart version: $CHART_VERSION"
      
      if [ -z "$APP_VERSION" ]; then
          warning "App version not specified"
      else
          success "App version: $APP_VERSION"
      fi
      echo ""
      
      # 4. Test template rendering
      echo "4️⃣  Testing template rendering..."
      if helm template "$RELEASE_NAME" "$CHART_DIR" > /dev/null 2>&1; then
          success "Templates rendered successfully"
      else
          error "Template rendering failed"
          helm template "$RELEASE_NAME" "$CHART_DIR"
          exit 1
      fi
      echo ""
      
      # 5. Dry-run installation
      echo "5️⃣  Testing dry-run installation..."
      if helm install "$RELEASE_NAME" "$CHART_DIR" --dry-run --debug > /dev/null 2>&1; then
          success "Dry-run installation successful"
      else
          error "Dry-run installation failed"
          exit 1
      fi
      echo ""
      
      # 6. Check for required Kubernetes resources
      echo "6️⃣  Checking generated resources..."
      MANIFESTS=$(helm template "$RELEASE_NAME" "$CHART_DIR")
      
      if echo "$MANIFESTS" | grep -q "kind: Deployment"; then
          success "Deployment found"
      else
          warning "No Deployment found"
      fi
      
      if echo "$MANIFESTS" | grep -q "kind: Service"; then
          success "Service found"
      else
          warning "No Service found"
      fi
      
      if echo "$MANIFESTS" | grep -q "kind: ServiceAccount"; then
          success "ServiceAccount found"
      else
          warning "No ServiceAccount found"
      fi
      echo ""
      
      # 7. Check for security best practices
      echo "7️⃣  Checking security best practices..."
      if echo "$MANIFESTS" | grep -q "runAsNonRoot: true"; then
          success "Running as non-root user"
      else
          warning "Not explicitly running as non-root"
      fi
      
      if echo "$MANIFESTS" | grep -q "readOnlyRootFilesystem: true"; then
          success "Using read-only root filesystem"
      else
          warning "Not using read-only root filesystem"
      fi
      
      if echo "$MANIFESTS" | grep -q "allowPrivilegeEscalation: false"; then
          success "Privilege escalation disabled"
      else
          warning "Privilege escalation not explicitly disabled"
      fi
      echo ""
      
      # 8. Check for resource limits
      echo "8️⃣  Checking resource configuration..."
      if echo "$MANIFESTS" | grep -q "resources:"; then
          if echo "$MANIFESTS" | grep -q "limits:"; then
              success "Resource limits defined"
          else
              warning "No resource limits defined"
          fi
          if echo "$MANIFESTS" | grep -q "requests:"; then
              success "Resource requests defined"
          else
              warning "No resource requests defined"
          fi
      else
          warning "No resources defined"
      fi
      echo ""
      
      # 9. Check for health probes
      echo "9️⃣  Checking health probes..."
      if echo "$MANIFESTS" | grep -q "livenessProbe:"; then
          success "Liveness probe configured"
      else
          warning "No liveness probe found"
      fi
      
      if echo "$MANIFESTS" | grep -q "readinessProbe:"; then
          success "Readiness probe configured"
      else
          warning "No readiness probe found"
      fi
      echo ""
      
      # 10. Check dependencies
      if [ -f "$CHART_DIR/Chart.yaml" ] && grep -q "^dependencies:" "$CHART_DIR/Chart.yaml"; then
          echo "🔟 Checking dependencies..."
          if helm dependency list "$CHART_DIR" > /dev/null 2>&1; then
              success "Dependencies valid"
      
              if [ -f "$CHART_DIR/Chart.lock" ]; then
                  success "Chart.lock file present"
              else
                  warning "Chart.lock file missing (run 'helm dependency update')"
              fi
          else
              error "Dependencies check failed"
          fi
          echo ""
      fi
      
      # 11. Check for values schema
      if [ -f "$CHART_DIR/values.schema.json" ]; then
          echo "1️⃣1️⃣ Validating values schema..."
          success "values.schema.json present"
      
          # Validate schema if jq is available
          if command -v jq &> /dev/null; then
              if jq empty "$CHART_DIR/values.schema.json" 2>/dev/null; then
                  success "values.schema.json is valid JSON"
              else
                  error "values.schema.json contains invalid JSON"
                  exit 1
              fi
          fi
          echo ""
      fi
      
      # Summary
      echo "═══════════════════════════════════════════════════════"
      echo "  Validation Complete!"
      echo "═══════════════════════════════════════════════════════"
      echo ""
      echo "Chart: $CHART_NAME"
      echo "Version: $CHART_VERSION"
      if [ -n "$APP_VERSION" ]; then
          echo "App Version: $APP_VERSION"
      fi
      echo ""
      success "All validations passed!"
      echo ""
      echo "Next steps:"
      echo "  • helm package $CHART_DIR"
      echo "  • helm install my-release $CHART_DIR"
      echo "  • helm test my-release"
      echo ""
      
  • SKILL.md 2.1 KB
    ---
    name: helm-chart-scaffolding
    description: Design, organize, and manage Helm charts for templating and packaging Kubernetes applications with reusable configurations. Use when creating Helm charts, packaging Kubernetes applications, or implementing templated deployments.
    ---
    
    # Helm Chart Scaffolding
    
    Comprehensive guidance for creating, organizing, and managing Helm charts for packaging and deploying Kubernetes applications.
    
    ## Purpose
    
    This skill provides step-by-step instructions for building production-ready Helm charts, including chart structure, templating patterns, values management, and validation strategies.
    
    ## When to Use This Skill
    
    Use this skill when you need to:
    
    - Create new Helm charts from scratch
    - Package Kubernetes applications for distribution
    - Manage multi-environment deployments with Helm
    - Implement templating for reusable Kubernetes manifests
    - Set up Helm chart repositories
    - Follow Helm best practices and conventions
    
    ## Detailed patterns and worked examples
    
    Detailed pattern documentation lives in `references/details.md`. Read that file when the navigation tier above is insufficient.
    
    ## Best Practices
    
    1. **Use semantic versioning** for chart and app versions
    2. **Document all values** in values.yaml with comments
    3. **Use template helpers** for repeated logic
    4. **Validate charts** before packaging
    5. **Pin dependency versions** explicitly
    6. **Use conditions** for optional resources
    7. **Follow naming conventions** (lowercase, hyphens)
    8. **Include NOTES.txt** with usage instructions
    9. **Add labels** consistently using helpers
    10. **Test installations** in all environments
    
    ## Troubleshooting
    
    **Template rendering errors:**
    
    ```bash
    helm template my-app ./my-app --debug
    ```
    
    **Dependency issues:**
    
    ```bash
    helm dependency update
    helm dependency list
    ```
    
    **Installation failures:**
    
    ```bash
    helm install my-app ./my-app --dry-run --debug
    kubectl get events --sort-by='.lastTimestamp'
    ```
    
    
    ## Related Skills
    
    - `k8s-manifest-generator` - For creating base Kubernetes manifests
    - `gitops-workflow` - For automated Helm chart deployments
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related