How helm install turns the chart on disk into running objects on the fakhri-k8 EKS cluster.
Render pipeline — 6 stages
Chart.yaml · values.yaml · templates/* · _helpers.tpl · optional -f envs/a.yaml
You run one helm command. Helm reads the chart and any override file.
Go templating merges values + .Release.*, walks templates/, emits one multi-doc YAML.
Manifest sent to the k8s API server. Helm records the revision in a Secret.
objectsControllers act: Deployment → ReplicaSet → Pod. Scheduler places Pods on EKS nodes.
podsESO, AWS Load Balancer Controller, and metrics-server finish the job.
1 · Inputs on disk
2 · command ↓
upgrade --install = create if absent, else new revision.
3 · Render — Go template engine (client-side, in Helm)
Merged values
values.yaml + -f envs/a.yaml (override) + .Release.Name planpal + .Release.Namespace
Go template engine
Multi-doc YAML
--- kind: Namespace ... --- kind: Deployment metadata: name: planpal-backend ... --- (× many docs)
5 · Reconcile
Controllers reconcile the declared state. HPA scales replicas via metrics-server.
6 · Cluster add-ons
Template → object mapbill of materials · rendered from the chart, exact counts
| Source file | Rendered objects |
|---|---|
| templates/namespace.yaml | 1 Namespace · 1 ServiceAccount planpal-backend |
| templates/apps.yaml | 5 Deployment · 2 Service · 5 HPA · 2 PDB ← one {{ range }} loop, see DETAIL A |
| templates/deps.yaml | 2 Deployment redis, nats · 2 Service (these 2 also count toward the 7 Deployment total) |
| templates/external-secrets.yaml | 1 ClusterSecretStore · 4 ExternalSecret |
| templates/ingress.yaml | 1 Ingress (ALB) |
| templates/seed-job.yaml | 1 Job seed-admin (runs once) |
| Σ total | 7 Deployment · 4 Service · 5 HPA · 2 PDB · 1 Ingress · 1 Job · 1 Namespace · 1 ServiceAccount · 1 ClusterSecretStore · 4 ExternalSecret |
One {{ range .Values.apps }} over a 5-entry map builds 5 Deployments. Conditionals add the extras: a Service if service:, an HPA if hpa:, a PDB if pdb:.
apps.yaml → 5 Deployment · 2 Service · 5 HPA · 2 PDB. The redis + nats Deployments come from deps.yaml, not this loop — they are the other 2 in the total of 7.
Each helm install lands in its own namespace + ALB + ClusterSecretStore, all defaulting to .Release.Name via _helpers.tpl.
planpal-a
planpal-b
planpal.namespace = default .Release.Name → planpal-a / planpal-b planpal.storeName = per-release CSS The empty gutter is the isolation: no connector crosses it. Two releases share nothing on the cluster.