Kubernetes: Kustomize and Helm
This repo supports two deployment paths for the same app. When changing any Kubernetes resource, update both so minikube, dev, and prod stay consistent whether users deploy with Kustomize or Helm.
Two paths, same behavior
| Path |
Location |
How envs differ |
| Kustomize |
k8s/base/ + k8s/overlays/{minikube,dev,prod}/ |
Patches and extra resources per overlay |
| Helm |
helm/contacts/ (templates + values) |
values-minikube.yaml, values-dev.sample.yaml, values-prod.sample.yaml |
Both must produce equivalent manifests for each environment (same probes, env vars, volumes, service types, ingress where applicable).
Kustomize layout
- Base (
k8s/base/): shared resources — contacts-service.yaml, deployment.yaml, migration-job.yaml. Change here only when all envs share the change.
- Overlays (
k8s/overlays/<env>/): patches (e.g. deployment-patch.yaml, service-patch.yaml, migration-job-patch.yaml) and extra resources (e.g. pvc.yaml for sqlite, postgres StatefulSet/Service/ConfigMap, ingress.yaml, managed-certificate.yaml for prod).
Apply with: kubectl apply -k k8s/overlays/<env> (Cloud Build uses this for dev/prod).
Helm layout
- Templates (
helm/contacts/templates/): one set of templates that branch on values:
database.engine: sqlite → PVC, file-based URL; postgres → ConfigMap + Secret, postgres services + StatefulSet.
ingress.enabled: true → Ingress + ManagedCertificate; false → no ingress.
- Values:
values.yaml (defaults), values-minikube.yaml, values-dev.sample.yaml, values-prod.sample.yaml. Committed samples; values-dev.yaml / values-prod.yaml are gitignored for secrets/overrides.
Deploy with: helm upgrade --install contacts ./helm/contacts -f ./helm/contacts/values-<env>.yaml [--set ...].
Change checklist
When adding or modifying any K8s concern (container image, probes, env vars, volumes, service type, migration job, ingress, DB config):
Kustomize
- Shared change? Edit
k8s/base/ (e.g. deployment.yaml, migration-job.yaml, contacts-service.yaml).
- Env-specific? Edit or add files in the right overlay(s) under
k8s/overlays/minikube/, k8s/overlays/dev/, or k8s/overlays/prod/ (patches and/or new YAML).
Helm
- Update the corresponding template(s) in
helm/contacts/templates/ (e.g. deployment.yaml, migration-job.yaml, service.yaml, ingress.yaml, pvc.yaml, postgres resources).
- Use
{{- if eq .Values.database.engine "sqlite" }} / postgres and {{- if .Values.ingress.enabled }} so behavior matches overlays.
- Adjust default or env-specific values in
values.yaml or values-minikube.yaml / values-*-.sample.yaml as needed.
Verify
- Kustomize:
kubectl kustomize k8s/overlays/<env> and spot-check key resources.
- Helm:
helm template contacts ./helm/contacts -f ./helm/contacts/values-<env>.yaml and compare with the Kustomize output for that env (same structure, env vars, and options).
Environments
Use the infrastructure skill to ensure minikube, dev, and prod are all considered; the k8s skill ensures both Kustomize and Helm reflect that.
Resource parity (quick reference)
| Resource |
Kustomize |
Helm template |
| Deployment |
base + overlay patches |
deployment.yaml |
| Service |
base + overlay patch (type) |
service.yaml |
| Migration Job |
base + overlay patches |
migration-job.yaml |
| PVC (SQLite) |
overlay pvc.yaml |
pvc.yaml (if sqlite) |
| Postgres (prod) |
overlay StatefulSet, services, configmap |
statefulset.yaml, postgres-services.yaml, configmap.yaml (if postgres) |
| Ingress + cert (prod) |
overlay |
ingress.yaml, managed-certificate.yaml (if ingress.enabled) |
CI currently uses the Kustomize path; the Helm path is optional (see cloudbuild.yaml and DEPLOYMENT_ARCHITECTURE.md). Even when only Kustomize is used in CI, keep the Helm chart in sync so local or future Helm-based deploys match.
Source: juancavallotti/k8s-gcp-reference-architecture — distributed by TomeVault.
1---2name: juancavallotti-k8s-gcp-reference-architecture-kubernetes3description: Kubernetes: Kustomize and Helm4---5# Kubernetes: Kustomize and Helm67This repo supports **two deployment paths** for the same app. When changing any Kubernetes resource, **update both** so minikube, dev, and prod stay consistent whether users deploy with Kustomize or Helm.89## Two paths, same behavior1011| Path | Location | How envs differ |12|------|----------|-----------------|13| **Kustomize** | `k8s/base/` + `k8s/overlays/{minikube,dev,prod}/` | Patches and extra resources per overlay |14| **Helm** | `helm/contacts/` (templates + values) | `values-minikube.yaml`, `values-dev.sample.yaml`, `values-prod.sample.yaml` |1516Both must produce equivalent manifests for each environment (same probes, env vars, volumes, service types, ingress where applicable).1718## Kustomize layout1920- **Base** (`k8s/base/`): shared resources — `contacts-service.yaml`, `deployment.yaml`, `migration-job.yaml`. Change here only when all envs share the change.21- **Overlays** (`k8s/overlays/<env>/`): patches (e.g. `deployment-patch.yaml`, `service-patch.yaml`, `migration-job-patch.yaml`) and extra resources (e.g. `pvc.yaml` for sqlite, postgres `StatefulSet`/`Service`/`ConfigMap`, `ingress.yaml`, `managed-certificate.yaml` for prod).2223Apply with: `kubectl apply -k k8s/overlays/<env>` (Cloud Build uses this for dev/prod).2425## Helm layout2627- **Templates** (`helm/contacts/templates/`): one set of templates that branch on values:28 - `database.engine`: `sqlite` → PVC, file-based URL; `postgres` → ConfigMap + Secret, postgres services + StatefulSet.29 - `ingress.enabled`: `true` → Ingress + ManagedCertificate; `false` → no ingress.30- **Values**: `values.yaml` (defaults), `values-minikube.yaml`, `values-dev.sample.yaml`, `values-prod.sample.yaml`. Committed samples; `values-dev.yaml` / `values-prod.yaml` are gitignored for secrets/overrides.3132Deploy with: `helm upgrade --install contacts ./helm/contacts -f ./helm/contacts/values-<env>.yaml [--set ...]`.3334## Change checklist3536When adding or modifying any K8s concern (container image, probes, env vars, volumes, service type, migration job, ingress, DB config):37381. **Kustomize**39 - Shared change? Edit `k8s/base/` (e.g. `deployment.yaml`, `migration-job.yaml`, `contacts-service.yaml`).40 - Env-specific? Edit or add files in the right overlay(s) under `k8s/overlays/minikube/`, `k8s/overlays/dev/`, or `k8s/overlays/prod/` (patches and/or new YAML).41422. **Helm**43 - Update the corresponding template(s) in `helm/contacts/templates/` (e.g. `deployment.yaml`, `migration-job.yaml`, `service.yaml`, `ingress.yaml`, `pvc.yaml`, postgres resources).44 - Use `{{- if eq .Values.database.engine "sqlite" }}` / `postgres` and `{{- if .Values.ingress.enabled }}` so behavior matches overlays.45 - Adjust default or env-specific values in `values.yaml` or `values-minikube.yaml` / `values-*-.sample.yaml` as needed.46473. **Verify**48 - Kustomize: `kubectl kustomize k8s/overlays/<env>` and spot-check key resources.49 - Helm: `helm template contacts ./helm/contacts -f ./helm/contacts/values-<env>.yaml` and compare with the Kustomize output for that env (same structure, env vars, and options).50514. **Environments** 52 Use the **infrastructure** skill to ensure minikube, dev, and prod are all considered; the k8s skill ensures both Kustomize and Helm reflect that.5354## Resource parity (quick reference)5556| Resource | Kustomize | Helm template |57|----------|-----------|---------------|58| Deployment | base + overlay patches | `deployment.yaml` |59| Service | base + overlay patch (type) | `service.yaml` |60| Migration Job | base + overlay patches | `migration-job.yaml` |61| PVC (SQLite) | overlay `pvc.yaml` | `pvc.yaml` (if sqlite) |62| Postgres (prod) | overlay StatefulSet, services, configmap | `statefulset.yaml`, `postgres-services.yaml`, `configmap.yaml` (if postgres) |63| Ingress + cert (prod) | overlay | `ingress.yaml`, `managed-certificate.yaml` (if ingress.enabled) |6465CI currently uses the **Kustomize** path; the Helm path is optional (see `cloudbuild.yaml` and `DEPLOYMENT_ARCHITECTURE.md`). Even when only Kustomize is used in CI, keep the Helm chart in sync so local or future Helm-based deploys match.6667---68> Source: [juancavallotti/k8s-gcp-reference-architecture](https://github.com/juancavallotti/k8s-gcp-reference-architecture) — distributed by [TomeVault](https://tomevault.io).69<!-- tomevault:4.0:skill_md:2026-06-16 -->