helm-chart-scaffolding

Helm Chart Scaffolding

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "helm-chart-scaffolding" with this command: npx skills add oimiragieo/agent-studio/oimiragieo-agent-studio-helm-chart-scaffolding

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

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:

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

  1. Configure Chart.yaml

Chart metadata defines the package:

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:

Source code repository

sources:

Homepage

home: https://example.com

Chart icon

icon: https://example.com/icon.png

Dependencies

dependencies:

Reference: See assets/Chart.yaml.template for complete example

  1. Design values.yaml Structure

Organize values hierarchically:

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

  1. Create Template Files

Use Go templating with Helm functions:

templates/deployment.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 }}

  1. Create Template Helpers

templates/_helpers.tpl:

{{/* 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 }}

  1. Manage Dependencies

Add dependencies in Chart.yaml:

dependencies:

Update dependencies:

helm dependency update helm dependency build

Override dependency values:

values.yaml

postgresql: enabled: true auth: database: myapp username: myapp password: changeme primary: persistence: enabled: true size: 10Gi

  1. Test and Validate

Validation commands:

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:

#!/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

  1. Package and Distribute

Package the chart:

helm package my-app/

Creates: my-app-1.0.0.tgz

Create chart repository:

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:

helm repo add my-repo https://charts.example.com helm repo update helm install my-app my-repo/my-app

  1. 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:

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:

helm install my-app ./my-app -f values-prod.yaml --namespace production

  1. Implement Hooks and Tests

Pre-install hook:

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:

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:

helm test my-app

Common Patterns

Pattern 1: Conditional Resources

{{- if .Values.ingress.enabled }} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ include "my-app.fullname" . }} spec:

...

{{- end }}

Pattern 2: Iterating Over Lists

env: {{- range .Values.env }}

  • name: {{ .name }} value: {{ .value | quote }} {{- end }}

Pattern 3: Including Files

data: config.yaml: | {{- .Files.Get "config/application.yaml" | nindent 4 }}

Pattern 4: Global Values

global: imageRegistry: docker.io imagePullSecrets: - name: regcred

Use in templates:

image: {{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}

Best Practices

  • Use semantic versioning for chart and app versions

  • Document all values in values.yaml with comments

  • Use template helpers for repeated logic

  • Validate charts before packaging

  • Pin dependency versions explicitly

  • Use conditions for optional resources

  • Follow naming conventions (lowercase, hyphens)

  • Include NOTES.txt with usage instructions

  • Add labels consistently using helpers

  • 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'

Reference Files

  • assets/Chart.yaml.template

  • Chart metadata template

  • assets/values.yaml.template

  • Values structure template

  • scripts/validate-chart.sh

  • Validation script

  • references/chart-structure.md

  • Detailed chart organization

Related Skills

  • k8s-manifest-generator

  • For creating base Kubernetes manifests

  • gitops-workflow

  • For automated Helm chart deployments

Memory Protocol (MANDATORY)

Before starting:

cat C:\dev\projects\agent-studio.claude\context\memory\learnings.md

After completing:

  • New pattern -> C:\dev\projects\agent-studio.claude\context\memory\learnings.md

  • Issue found -> C:\dev\projects\agent-studio.claude\context\memory\issues.md

  • Decision made -> C:\dev\projects\agent-studio.claude\context\memory\decisions.md

ASSUME INTERRUPTION: If it's not in memory, it didn't happen.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

filesystem

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

slack-notifications

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

chrome-browser

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

text-to-sql

No summary provided by upstream source.

Repository SourceNeeds Review