---
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.
enabled: false
source: github:JuanJoseGonGi/skills
imported-from: github:JuanJoseGonGi/skills
---

# Helm Chart Scaffolding

Create, organize, and manage production-ready Helm charts for packaging and deploying Kubernetes applications.

## When to Use

- 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

## Workflow

### 1. Initialize Chart Structure

```bash
helm create my-app
```

Standard 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
```

> **Detail:** See `references/chart-structure.md` for extended structure with CRDs, schema, and files/

### 2. Configure Chart.yaml

Key fields:

```yaml
apiVersion: v2
name: my-app
description: A Helm chart for My Application
type: application          # or library
version: 1.0.0             # Chart version (SemVer)
appVersion: "2.1.0"        # Application version
kubeVersion: ">=1.24.0"    # K8s compatibility

dependencies:
  - name: postgresql
    version: "12.0.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
```

> **Detail:** See `references/values-templates.md` for complete Chart.yaml with maintainers, keywords, icons, multi-dependency setup

### 3. Design values.yaml

Organize values hierarchically — group by concern:

```yaml
image:
  repository: myapp
  tag: "1.0.0"
  pullPolicy: IfNotPresent

replicaCount: 3

service:
  type: ClusterIP
  port: 80
  targetPort: 8080

ingress:
  enabled: false
  className: nginx
  hosts:
    - host: app.example.com
      paths:
        - path: /
          pathType: Prefix

resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "500m"

autoscaling:
  enabled: false
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 80
```

> **Detail:** See `references/values-templates.md` for full values.yaml with env, configMap, dependency overrides, and multi-environment files

### 4. Create Templates

Use Go templating with Helm functions. Core deployment pattern:

```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:
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
        resources:
          {{- toYaml .Values.resources | nindent 12 }}
```

> **Detail:** See `references/template-patterns.md` for full deployment, _helpers.tpl, hooks, and test templates

### 5. Template Helpers

Define in `templates/_helpers.tpl` — essential helpers:

- `my-app.name` — chart name, truncated to 63 chars
- `my-app.fullname` — release-qualified name
- `my-app.labels` — standard Kubernetes labels
- `my-app.selectorLabels` — pod selector labels

> **Detail:** See `references/template-patterns.md` for complete helper implementations

### 6. Manage Dependencies

```bash
helm dependency update    # Download dependencies
helm dependency build     # Rebuild from lock file
helm dependency list      # Show dependency status
```

Override dependency values in your `values.yaml`:

```yaml
postgresql:
  enabled: true
  auth:
    database: myapp
    username: myapp
  primary:
    persistence:
      size: 10Gi
```

### 7. Test and Validate

```bash
helm lint my-app/                                    # Lint chart
helm template my-app ./my-app                        # Render templates
helm template my-app ./my-app -f values-prod.yaml    # Render with env values
helm install my-app ./my-app --dry-run --debug        # Dry-run install
helm show values ./my-app                             # Show computed values
helm test my-app                                      # Run test pods
```

### 8. Package and Distribute

```bash
# Package
helm package my-app/               # Creates my-app-1.0.0.tgz

# Create repository index
helm repo index . --url https://charts.example.com

# Use from repository
helm repo add my-repo https://charts.example.com
helm repo update
helm install my-app my-repo/my-app
```

### 9. Multi-Environment Configuration

Maintain per-environment values files:

```
values.yaml          # Defaults
values-dev.yaml      # Development overrides
values-staging.yaml  # Staging overrides
values-prod.yaml     # Production overrides
```

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

> **Detail:** See `references/values-templates.md` for complete production values example

## Common Template Patterns

| Pattern | Syntax | Use Case |
|---------|--------|----------|
| Conditional | `{{- if .Values.x.enabled }}` | Optional resources |
| Iteration | `{{- range .Values.env }}` | Lists of items |
| File include | `{{ .Files.Get "config/app.yaml" }}` | Embed config files |
| Global values | `{{ .Values.global.imageRegistry }}` | Cross-subchart sharing |
| Quote strings | `{{ .Values.name \| quote }}` | Safe string values |
| Default | `{{ .Values.tag \| default .Chart.AppVersion }}` | Fallback values |
| Indent | `{{- toYaml .Values.x \| nindent 8 }}` | Nested YAML blocks |

> **Detail:** See `references/template-patterns.md` for full examples of each pattern

## Hooks

Control execution at lifecycle points via annotations:

```yaml
annotations:
  "helm.sh/hook": pre-install        # When to run
  "helm.sh/hook-weight": "-5"        # Order (-5 to 5)
  "helm.sh/hook-delete-policy": hook-succeeded
```

Hook types: `pre-install`, `post-install`, `pre-upgrade`, `post-upgrade`, `pre-delete`, `post-delete`, `pre-rollback`, `post-rollback`, `test`

> **Detail:** See `references/template-patterns.md` for hook Job and test Pod examples

## Best Practices

1. **Semantic versioning** for chart and app versions
2. **Document all values** in values.yaml with comments
3. **Use template helpers** for repeated logic (names, labels)
4. **Validate charts** with `helm lint` and `--dry-run` before packaging
5. **Pin dependency versions** explicitly
6. **Use conditions** (`enabled: false`) for optional resources
7. **Follow naming conventions** — lowercase, hyphens, 63-char limit
8. **Include NOTES.txt** with post-install usage instructions
9. **Add labels** consistently using helpers
10. **Test installations** in all target environments

## Troubleshooting

```bash
helm template my-app ./my-app --debug     # Debug template rendering
helm dependency update && helm dependency list   # Fix dependency issues
helm install my-app ./my-app --dry-run --debug   # Debug installation
kubectl get events --sort-by='.lastTimestamp'     # Check K8s events
```

## Reference Files

- `references/chart-structure.md` — Full chart directory structure, Chart.yaml spec, CRDs, versioning, hooks, .helmignore
- `references/values-templates.md` — Complete values.yaml, Chart.yaml examples, multi-env configs, dependency overrides
- `references/template-patterns.md` — Deployment template, _helpers.tpl, conditional/iteration patterns, hooks, tests

## Related Skills

- `k8s-manifest-generator` — Base Kubernetes manifests
- `gitops-workflow` — Automated Helm chart deployments
