Helm Chart Scaffolding
Seth HobsonCommunityCreated by Seth Hobson
- Skill
- Tool integration
- Cloud and DevOps
- MIT
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach to creating and maintaining Helm charts, the standard package manager for Kubernetes. It covers the essential directory structure, metadata configuration in Chart.yaml, hierarchical values management, and the implementation of reusable Go-based templates. Designed for developers and DevOps engineers, it ensures that Kubernetes applications are packaged consistently, follow best practices for versioning and dependency management, and are ready for multi-environment deployment.
What it does
- Defines standard directory structures for Helm charts
- Provides templates for Chart.yaml and values.yaml files
- Explains how to implement Go templating for Kubernetes manifests
- Guides the configuration of chart dependencies and conditions
- Offers best practices for versioning, labeling, and validation
- Includes troubleshooting commands for rendering and installation
When to use it
- When creating new Helm charts from scratch
- When packaging Kubernetes applications for distribution
- When implementing templated deployments for multiple environments
- When needing to manage complex application dependencies
- When standardizing Kubernetes manifest management across a team
Advantages
- Promotes consistency through standardized file structures
- Enables reusable configurations via hierarchical values
- Simplifies complex deployments with template helpers
- Supports production-ready practices like semantic versioning
- Provides clear paths for debugging and validation
Usage examples
- “How do I initialize a new Helm chart structure?”
- The agent will guide you to use the 'helm create' command and explain the purpose of the generated directories like templates/ and charts/.
- “How can I make my deployment replicas configurable in values.yaml?”
- The agent will show you how to define a 'replicaCount' key in values.yaml and reference it in your deployment.yaml template using '{{ .Values.replicaCount }}'.
- “How do I troubleshoot a template rendering error?”
- The agent will provide the 'helm template' command with the '--debug' flag to inspect the generated manifests before installation.
- “What is the difference between an application chart and a library chart?”
- The agent will explain that application charts are installable units, while library charts are used as dependencies to share template helpers.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/wshobson/helm-chart-scaffolding/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip helm-chart-scaffolding.zip -d .agents/skills
Documentation by Seth Hobson
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
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 --debugDependency issues:
helm dependency update
helm dependency listInstallation 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 manifestsgitops-workflow- For automated Helm chart deployments
Files
- ATTRIBUTION.mdAdded by AutoGineer1008 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md2.1 KiB
- assets/Chart.yaml.template801 B
- assets/values.yaml.template3.1 KiB
- references/chart-structure.md11.2 KiB
- references/details.md9.2 KiB
- scripts/validate-chart.shScript6.4 KiB
references/chart-structure.md
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.confChart.yaml Specification
API Version v2 (Helm 3+)
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: [email protected]
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: dbChart Types
Application Chart
type: applicationStandard Kubernetes applications
Can be installed and managed
Contains templates for K8s resources
Library Chart
type: libraryShared template helpers
Cannot be installed directly
Used as dependency by other charts
No templates/ directory
Values Files Organization
values.yaml (defaults)
# 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: 30svalues.schema.json (validation)
{
"$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.yamlPartial templates: Prefix with underscore
_helpers.tplTests: Place in
templates/tests/CRDs: Place in
crds/(not templated)
Common Templates
_helpers.tpl
{{/*
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
# 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.dbManaging Dependencies
# Update dependencies
helm dependency update
# List dependencies
helm dependency list
# Build dependencies
helm dependency buildChart.lock
Generated automatically by helm dependency update:
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/
*.imlCustom Resource Definitions (CRDs)
Place CRDs in crds/ directory:
crds/
├── my-app-crd.yaml
└── another-crd.yamlImportant 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-crdsto 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
version: 2.3.1 # Chart version
appVersion: "1.5.0" # Application versionChart Testing
Test Files
# 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: NeverRunning Tests
helm test my-release
helm test my-release --logsHooks
Helm hooks allow intervention at specific points:
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-succeededHook Types
pre-install: Before templates renderedpost-install: After all resources loadedpre-delete: Before any resources deletedpost-delete: After all resources deletedpre-upgrade: Before upgradepost-upgrade: After upgradepre-rollback: Before rollbackpost-rollback: After rollbacktest: Run withhelm test
Hook Weight
Controls hook execution order (-5 to 5, lower runs first)
Hook Deletion Policies
before-hook-creation: Delete previous hook before new onehook-succeeded: Delete after successful executionhook-failed: Delete if hook fails
Best Practices
Use helpers for repeated template logic
Quote strings in templates:
{{ .Values.name | quote }}Validate values with values.schema.json
Document all values in values.yaml
Use semantic versioning for chart versions
Pin dependency versions exactly
Include NOTES.txt with usage instructions
Add tests for critical functionality
Use hooks for database migrations
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.tgzCreating Repository Index
helm repo index . --url https://charts.example.comRelated Resources
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs a command-line tool
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Seth Hobson
- Publisher
- Seth Hobson (Community)
- Source
- wshobson/agents · plugins/kubernetes-operations/skills/helm-chart-scaffolding · commit 4bde316
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Seth Hobson.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download helm-chart-scaffolding.zip