Skip to content

Commit 3875eeb

Browse files
aRustyDevclaude
andauthored
feat(skill): add structured workflow to k8s-helm-charts-dev (#817)
Add Research → Planning → Implementation workflow with approval gates, issue mapping, and extend/contribute strategy for complex Helm chart development. ### Added **Reference Files:** - extend-contribute-strategy.md - Fork vs copy decision, contribution workflow - research-phase-workflow.md - Structured research with approval gates - planning-phase-workflow.md - High-level and phase planning with issue mapping - implementation-workflow.md - Implementation with sanity checks and review stops - research-strategy.md - Expanded decision table, workflow selection - chart-complexity.md - Chart complexity classification - external-services.md - Common ports, env vars, connection strings **Templates:** - research-summary.md - Research findings documentation - high-level-plan.md - High-level chart plan - phase-plan.md - Per-phase implementation plan - issue-structure.md - GitHub issue hierarchy **Patterns:** - external-database.yaml - MySQL/PostgreSQL configuration - external-search.yaml - Elasticsearch/OpenSearch configuration - external-messaging.yaml - Airflow/Kafka/RabbitMQ/Redis configuration - multi-port-service.yaml - Multiple ports pattern - jvm-application.yaml - JVM heap/GC/JMX configuration - health-probes-multiport.yaml - Probes on different ports ### Changed - SKILL.md - Added "Structured Development Workflow" section - SKILL.md - Updated Reference Files list Closes #816 Closes #696 🤖 Generated with [Claude Code](https://claude.ai/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 044e24c commit 3875eeb

18 files changed

Lines changed: 4915 additions & 1 deletion

components/skills/k8s-helm-charts-dev/SKILL.md

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,95 @@ Use this skill when you need to:
2121
- Set up Helm chart repositories
2222
- Follow Helm best practices and conventions
2323

24+
## Chart Complexity Classification
25+
26+
Before starting, classify your chart to determine the appropriate approach:
27+
28+
| Level | Characteristics | CI Handling | Example |
29+
|-------|-----------------|-------------|---------|
30+
| **Simple** | Single container, no external deps, standard probes | Full lint + install | Static site, simple API |
31+
| **Standard** | Multiple resources, ConfigMaps/Secrets, optional deps | Full lint + install | Web app with ingress |
32+
| **Complex** | External services required, multi-port, JVM config | Lint only, skip install | OpenMetadata, data platforms |
33+
| **Operator** | CRDs, webhooks, cluster-wide resources | Lint only, manual test | Prometheus Operator |
34+
35+
**Quick Decision:**
36+
- Needs database/search/messaging at runtime? → **Complex** (exclude from install tests)
37+
- Has admin port separate from main port? → Check `assets/patterns/multi-port-service.yaml`
38+
- JVM application? → Check `assets/patterns/jvm-application.yaml`
39+
40+
> **Details**: See `references/chart-complexity.md` for full classification guide and CI configuration.
41+
42+
## Research Strategy
43+
44+
Before creating a chart, research the application:
45+
46+
1. **Check for official chart** - Many projects maintain their own Helm charts
47+
2. **Review Docker documentation** - Container entrypoint, environment variables, ports
48+
3. **Identify external dependencies** - What services does the app need?
49+
50+
**If documentation scraping fails**, use alternative methods:
51+
- Search GitHub for existing implementations
52+
- Check Docker Hub for environment variable documentation
53+
- Review Kubernetes deployment examples in project repos
54+
55+
> **Details**: See `references/research-strategy.md` for complete fallback strategies and information gathering checklist.
56+
57+
## Structured Development Workflow
58+
59+
For complex charts or when contributing to existing projects, use a structured approach:
60+
61+
### Workflow Selection
62+
63+
| Chart Complexity | Official Chart Exists | Workflow |
64+
|------------------|----------------------|----------|
65+
| Simple/Standard | No | **Fast Path** - Quick research, create, validate |
66+
| Simple/Standard | Yes (use as-is) | **Skip** - Use existing chart |
67+
| Complex/Operator | No | **Full Workflow** - Research → Plan → Implement |
68+
| Any | Yes (extend) | **Full Workflow** with contribution strategy |
69+
70+
### Research Phase
71+
72+
Systematically investigate the application before creating templates:
73+
1. Check for existing charts (official, community)
74+
2. Gather configuration details (image, ports, env vars)
75+
3. Document findings in structured format
76+
4. Get approval for complex applications
77+
78+
> **Details**: See `references/research-phase-workflow.md`
79+
80+
### Planning Phase
81+
82+
Translate research into actionable implementation plan:
83+
1. Create high-level plan with target features
84+
2. Break down into atomic components (phases)
85+
3. Draft phase plans for each component
86+
4. Get sequential approvals
87+
5. Map plans to GitHub issues (optional)
88+
89+
> **Details**: See `references/planning-phase-workflow.md`
90+
91+
### Implementation Phase
92+
93+
Execute with quality gates and review checkpoints:
94+
1. Create worktree and draft PR immediately
95+
2. Implement following phase plan
96+
3. Run sanity checks (lint, template, security)
97+
4. Pause for external review when needed
98+
5. Submit PR when complete, clean up worktree
99+
100+
> **Details**: See `references/implementation-workflow.md`
101+
102+
### Extending Existing Charts
103+
104+
When an official chart exists but needs improvements:
105+
1. Decide: fork repo vs copy locally
106+
2. Review upstream patterns and values schema
107+
3. Maintain compatibility for contribution
108+
4. Document differences and improvements
109+
5. Prepare upstream contribution (PR or patch)
110+
111+
> **Details**: See `references/extend-contribute-strategy.md`
112+
24113
## Helm Overview
25114

26115
**Helm** is the package manager for Kubernetes that:
@@ -499,6 +588,37 @@ global:
499588
image: {{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}
500589
```
501590
591+
## Pattern Templates
592+
593+
Ready-to-use patterns for common scenarios. Copy values and template sections to your chart.
594+
595+
### External Services
596+
597+
| Pattern | Use When | File |
598+
|---------|----------|------|
599+
| Database | Chart connects to MySQL or PostgreSQL | `assets/patterns/external-database.yaml` |
600+
| Search | Chart connects to Elasticsearch or OpenSearch | `assets/patterns/external-search.yaml` |
601+
| Messaging | Chart connects to Airflow, Kafka, RabbitMQ, or Redis | `assets/patterns/external-messaging.yaml` |
602+
603+
All patterns include:
604+
- Values structure with `existingSecret` support
605+
- Helper template functions
606+
- Environment variable configuration
607+
- Example configurations
608+
609+
### Application Architecture
610+
611+
| Pattern | Use When | File |
612+
|---------|----------|------|
613+
| Multi-Port Service | App has main + admin/metrics ports | `assets/patterns/multi-port-service.yaml` |
614+
| JVM Application | Java/Kotlin/Scala app needing heap/GC config | `assets/patterns/jvm-application.yaml` |
615+
| Health Probes (Multi-Port) | Different probes on different ports | `assets/patterns/health-probes-multiport.yaml` |
616+
617+
### Quick Reference
618+
619+
For port numbers, environment variables, and connection strings:
620+
- `references/external-services.md` - Common services reference table
621+
502622
## Best Practices
503623

504624
1. **Use semantic versioning** for chart and app versions
@@ -533,10 +653,36 @@ kubectl get events --sort-by='.lastTimestamp'
533653

534654
## Reference Files
535655

656+
### Chart Templates
536657
- `assets/Chart.yaml.template` - Chart metadata template
537658
- `assets/values.yaml.template` - Values structure template
538-
- `scripts/validate-chart.sh` - Validation script
659+
660+
### Pattern Files
661+
- `assets/patterns/external-database.yaml` - MySQL/PostgreSQL configuration
662+
- `assets/patterns/external-search.yaml` - Elasticsearch/OpenSearch configuration
663+
- `assets/patterns/external-messaging.yaml` - Airflow/Kafka/RabbitMQ/Redis configuration
664+
- `assets/patterns/multi-port-service.yaml` - Multiple ports pattern
665+
- `assets/patterns/jvm-application.yaml` - JVM heap/GC/JMX configuration
666+
- `assets/patterns/health-probes-multiport.yaml` - Probes on different ports
667+
668+
### Workflow Templates
669+
- `assets/templates/research-summary.md` - Research findings documentation
670+
- `assets/templates/high-level-plan.md` - High-level chart plan
671+
- `assets/templates/phase-plan.md` - Per-phase implementation plan
672+
- `assets/templates/issue-structure.md` - GitHub issue hierarchy
673+
674+
### References
539675
- `references/chart-structure.md` - Detailed chart organization
676+
- `references/chart-complexity.md` - Chart complexity classification guide
677+
- `references/research-strategy.md` - Documentation research and fallback strategies
678+
- `references/external-services.md` - Common ports, env vars, connection strings
679+
- `references/extend-contribute-strategy.md` - Extending and contributing to existing charts
680+
- `references/research-phase-workflow.md` - Research phase structured workflow
681+
- `references/planning-phase-workflow.md` - Planning phase structured workflow
682+
- `references/implementation-workflow.md` - Implementation phase with checkpoints
683+
684+
### Scripts
685+
- `scripts/validate-chart.sh` - Validation script
540686

541687
## Related Skills
542688

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# =============================================================================
2+
# External Database Configuration Pattern
3+
# =============================================================================
4+
# Use this pattern when chart connects to an EXISTING external database
5+
# rather than deploying a database as a subchart dependency.
6+
#
7+
# Supports: MySQL, PostgreSQL, MariaDB
8+
#
9+
# Usage:
10+
# 1. Copy the values section to your values.yaml
11+
# 2. Copy the helper templates to your _helpers.tpl
12+
# 3. Copy the environment variable section to your deployment.yaml
13+
# =============================================================================
14+
15+
# -----------------------------------------------------------------------------
16+
# VALUES.YAML SECTION
17+
# -----------------------------------------------------------------------------
18+
# Copy this to your values.yaml under a 'database:' key
19+
20+
database:
21+
# -- Database type: mysql, postgres, or mariadb
22+
type: mysql
23+
24+
# -- External database host (required)
25+
host: ""
26+
27+
# -- Database port (3306 for MySQL/MariaDB, 5432 for PostgreSQL)
28+
port: 3306
29+
30+
# -- Database name
31+
name: "app_db"
32+
33+
# -- Database username
34+
username: ""
35+
36+
# -- Database password (use existingSecret in production)
37+
password: ""
38+
39+
# -- Use existing Kubernetes secret for database credentials
40+
# If set, password field is ignored
41+
existingSecret: ""
42+
43+
# -- Key in existing secret containing the password
44+
existingSecretKey: "password"
45+
46+
# -- Additional JDBC connection parameters
47+
# MySQL example: "useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"
48+
# PostgreSQL example: "sslmode=require"
49+
params: ""
50+
51+
# -- Connection pool settings (if supported by application)
52+
pool:
53+
# -- Minimum pool size
54+
minSize: 5
55+
# -- Maximum pool size
56+
maxSize: 20
57+
# -- Connection timeout in milliseconds
58+
connectionTimeout: 30000
59+
60+
# -----------------------------------------------------------------------------
61+
# HELPERS.TPL SECTION
62+
# -----------------------------------------------------------------------------
63+
# Copy these helper templates to your templates/_helpers.tpl
64+
65+
# {{/*
66+
# Database JDBC URL
67+
# */}}
68+
# {{- define "<chart>.databaseUrl" -}}
69+
# {{- $params := "" }}
70+
# {{- if .Values.database.params }}
71+
# {{- $params = printf "?%s" .Values.database.params }}
72+
# {{- end }}
73+
# {{- if eq .Values.database.type "mysql" }}
74+
# {{- printf "jdbc:mysql://%s:%d/%s%s" .Values.database.host (int .Values.database.port) .Values.database.name $params }}
75+
# {{- else if eq .Values.database.type "mariadb" }}
76+
# {{- printf "jdbc:mariadb://%s:%d/%s%s" .Values.database.host (int .Values.database.port) .Values.database.name $params }}
77+
# {{- else if eq .Values.database.type "postgres" }}
78+
# {{- printf "jdbc:postgresql://%s:%d/%s%s" .Values.database.host (int .Values.database.port) .Values.database.name $params }}
79+
# {{- end }}
80+
# {{- end }}
81+
82+
# {{/*
83+
# Database driver class name
84+
# */}}
85+
# {{- define "<chart>.databaseDriver" -}}
86+
# {{- if eq .Values.database.type "mysql" }}
87+
# {{- "com.mysql.cj.jdbc.Driver" }}
88+
# {{- else if eq .Values.database.type "mariadb" }}
89+
# {{- "org.mariadb.jdbc.Driver" }}
90+
# {{- else if eq .Values.database.type "postgres" }}
91+
# {{- "org.postgresql.Driver" }}
92+
# {{- end }}
93+
# {{- end }}
94+
95+
# {{/*
96+
# Database dialect (for ORMs like Hibernate)
97+
# */}}
98+
# {{- define "<chart>.databaseDialect" -}}
99+
# {{- if eq .Values.database.type "mysql" }}
100+
# {{- "org.hibernate.dialect.MySQL8Dialect" }}
101+
# {{- else if eq .Values.database.type "mariadb" }}
102+
# {{- "org.hibernate.dialect.MariaDB103Dialect" }}
103+
# {{- else if eq .Values.database.type "postgres" }}
104+
# {{- "org.hibernate.dialect.PostgreSQL10Dialect" }}
105+
# {{- end }}
106+
# {{- end }}
107+
108+
# -----------------------------------------------------------------------------
109+
# DEPLOYMENT.YAML ENVIRONMENT SECTION
110+
# -----------------------------------------------------------------------------
111+
# Copy this to your deployment.yaml container env section
112+
113+
# env:
114+
# # Database connection details
115+
# - name: DB_TYPE
116+
# value: {{ .Values.database.type | quote }}
117+
# - name: DB_HOST
118+
# value: {{ .Values.database.host | quote }}
119+
# - name: DB_PORT
120+
# value: {{ .Values.database.port | quote }}
121+
# - name: DB_NAME
122+
# value: {{ .Values.database.name | quote }}
123+
# - name: DB_USER
124+
# value: {{ .Values.database.username | quote }}
125+
# - name: DB_PASSWORD
126+
# {{- if .Values.database.existingSecret }}
127+
# valueFrom:
128+
# secretKeyRef:
129+
# name: {{ .Values.database.existingSecret }}
130+
# key: {{ .Values.database.existingSecretKey }}
131+
# {{- else }}
132+
# value: {{ .Values.database.password | quote }}
133+
# {{- end }}
134+
# # Optional: JDBC URL (if application uses single URL)
135+
# - name: DB_URL
136+
# value: {{ include "<chart>.databaseUrl" . | quote }}
137+
# - name: DB_DRIVER
138+
# value: {{ include "<chart>.databaseDriver" . | quote }}
139+
140+
# -----------------------------------------------------------------------------
141+
# ALTERNATIVE: DATABASE_URL STYLE (Node.js, Rails, etc.)
142+
# -----------------------------------------------------------------------------
143+
# Some applications prefer a single connection URL
144+
145+
# env:
146+
# - name: DATABASE_URL
147+
# {{- if .Values.database.existingSecret }}
148+
# valueFrom:
149+
# secretKeyRef:
150+
# name: {{ .Values.database.existingSecret }}
151+
# key: database-url
152+
# {{- else }}
153+
# {{- if eq .Values.database.type "postgres" }}
154+
# value: "postgresql://{{ .Values.database.username }}:{{ .Values.database.password }}@{{ .Values.database.host }}:{{ .Values.database.port }}/{{ .Values.database.name }}"
155+
# {{- else }}
156+
# value: "mysql://{{ .Values.database.username }}:{{ .Values.database.password }}@{{ .Values.database.host }}:{{ .Values.database.port }}/{{ .Values.database.name }}"
157+
# {{- end }}
158+
# {{- end }}
159+
160+
# -----------------------------------------------------------------------------
161+
# NOTES.TXT SECTION
162+
# -----------------------------------------------------------------------------
163+
# Add database connection info to NOTES.txt
164+
165+
# {{- if .Values.database.host }}
166+
# Database Configuration:
167+
# Type: {{ .Values.database.type }}
168+
# Host: {{ .Values.database.host }}:{{ .Values.database.port }}
169+
# Database: {{ .Values.database.name }}
170+
# User: {{ .Values.database.username }}
171+
# {{- else }}
172+
# WARNING: Database host is not configured!
173+
# Set database.host in your values to connect to your database.
174+
# {{- end }}
175+
176+
# -----------------------------------------------------------------------------
177+
# COMMON PORTS REFERENCE
178+
# -----------------------------------------------------------------------------
179+
# | Database | Default Port |
180+
# |------------|--------------|
181+
# | MySQL | 3306 |
182+
# | PostgreSQL | 5432 |
183+
# | MariaDB | 3306 |
184+
# | MongoDB | 27017 |
185+
# | Cassandra | 9042 |
186+
# | CockroachDB| 26257 |
187+
188+
# -----------------------------------------------------------------------------
189+
# EXAMPLE VALUES FOR DIFFERENT SCENARIOS
190+
# -----------------------------------------------------------------------------
191+
192+
# MySQL in same cluster:
193+
# database:
194+
# type: mysql
195+
# host: mysql.database.svc.cluster.local
196+
# port: 3306
197+
# name: myapp
198+
# username: myapp
199+
# existingSecret: myapp-db-credentials
200+
# existingSecretKey: password
201+
202+
# PostgreSQL with SSL:
203+
# database:
204+
# type: postgres
205+
# host: postgres.example.com
206+
# port: 5432
207+
# name: myapp
208+
# username: myapp
209+
# existingSecret: myapp-db-credentials
210+
# params: "sslmode=require"
211+
212+
# AWS RDS MySQL:
213+
# database:
214+
# type: mysql
215+
# host: myapp.xxxxx.us-east-1.rds.amazonaws.com
216+
# port: 3306
217+
# name: myapp
218+
# username: admin
219+
# existingSecret: rds-credentials
220+
# params: "useSSL=true&requireSSL=true"

0 commit comments

Comments
 (0)