feat(helm): forbid hardcoded namespaces and release names

Add hard rule: charts must be fully agnostic about installation target.
- Never hardcode namespace in any template — use .Release.Namespace or omit
- Never hardcode release name — use .Release.Name / fullname helper
- Enforce IaC principle: deployer decides where, chart describes what
This commit is contained in:
moilanik 2026-03-10 08:43:43 +02:00
parent 407c0a560c
commit cb402009fe

View File

@ -11,6 +11,61 @@ Before writing a new template, config, or resource:
---
## 🚫 Never Hardcode Namespace, Release Name, or Installation-Specific Values
**A Helm chart must be fully agnostic about where and how it is installed.**
This is a hard rule — no exceptions.
### Namespace
Never hardcode a namespace in any template. The namespace is set by the deployer at install time.
```yaml
# ❌ FORBIDDEN — always
metadata:
namespace: my-app
namespace: production
namespace: default
# ✅ Required — or omit namespace entirely and let Helm inject it
metadata:
namespace: {{ .Release.Namespace }}
```
If a resource must reference another namespace (e.g. a NetworkPolicy peer), expose it as a required value:
```yaml
metadata:
namespace: {{ required "global.namespace is required" .Values.global.targetNamespace }}
```
### Release Name
Never hardcode a release name. Use `.Release.Name` to derive resource names:
```yaml
# ❌ FORBIDDEN
name: my-app-service
name: myapp-ingress
# ✅ Required
name: {{ include "mychart.fullname" . }}
# or
name: {{ .Release.Name }}-service
```
### Why — IaC Principle
The chart is infrastructure code. It must be deployable to any cluster, any namespace, any environment, by any deployer — without editing the chart itself. Installation-specific decisions belong exclusively in `values.<installation>.yaml` in the deployment repo.
```
❌ Wrong: chart decides where it lives
✅ Right: deployer decides where it lives — chart only describes what it is
```
---
## 🏠 Resource Ownership
**Every Kubernetes resource must have exactly one owner. Never duplicate.**