Initial commit
This commit is contained in:
544
skills/helm-chart-scaffolding/SKILL.md
Normal file
544
skills/helm-chart-scaffolding/SKILL.md
Normal file
@@ -0,0 +1,544 @@
|
||||
---
|
||||
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
|
||||
|
||||
## 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 }}
|
||||
```
|
||||
|
||||
## 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'
|
||||
```
|
||||
|
||||
## 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
|
||||
Reference in New Issue
Block a user