Helm & GitOps
Helm charts and templating, release tracking and rollback, Helm vs Kustomize, the GitOps pull model, and ArgoCD drift reconciliation.
8 questions
JuniorTheoryCommonWhat is GitOps, and what does the pull-based reconciliation model mean?
What is GitOps, and what does the pull-based reconciliation model mean?
GitOps makes Git the single source of truth for desired cluster state. An in-cluster controller continuously pulls the repo and reconciles it. Pull-based means the agent applies changes from inside, not push CI running kubectl apply — so no cluster credentials leave the trust boundary.
Common mistakes
- ✗Thinking CI running
kubectl apply(push CD) is GitOps - ✗Believing Git stores live cluster state rather than desired state
- ✗Missing that a pull-based agent avoids handing out cluster credentials
Follow-up questions
- →Why is a pull-based agent more secure than a push-based CI deploy?
- →What is the single source of truth in a GitOps setup, and why?
JuniorTheoryCommonWhat is Helm, and what problem do charts solve for Kubernetes deployments?
What is Helm, and what problem do charts solve for Kubernetes deployments?
Helm is the package manager for Kubernetes. A chart bundles an app's templated manifests plus a values.yaml of defaults, so one parameterized package installs across environments. It replaces copy-pasting near-identical YAML per env, and helm install tracks it as a versioned release.
Common mistakes
- ✗Thinking Helm builds or ships container images rather than packaging manifests
- ✗Believing a chart is static YAML with no templating or values
- ✗Confusing Helm's packaging with a GitOps controller's continuous reconciliation
Follow-up questions
- →What does
helm upgradedo that a freshhelm installdoes not? - →Why is templating a chart safer than keeping one manifest copy per environment?
JuniorTheoryOccasionalWhat are the main parts of a Helm chart — Chart.yaml, values.yaml, and templates/?
What are the main parts of a Helm chart — Chart.yaml, values.yaml, and templates/?
Chart.yaml is the metadata — name, version, and chart dependencies. values.yaml holds the default configuration a user overrides at install. templates/ holds the Go-templated manifests Helm renders by injecting values into them, and charts/ vendors subchart dependencies.
Common mistakes
- ✗Confusing
Chart.yaml(metadata) withvalues.yaml(default config) - ✗Thinking
templates/holds finished manifests rather than templated source - ✗Not knowing chart dependencies are declared in
Chart.yaml
Follow-up questions
- →How do you override a value in
values.yamlwithout editing the chart itself? - →Where does a subchart's own
values.yamlsit relative to the parent chart's?
JuniorTheoryOccasionalHow does Helm track releases, and how do you roll one back to a previous version?
How does Helm track releases, and how do you roll one back to a previous version?
Each helm install/upgrade creates a numbered release revision, and Helm stores each revision's rendered manifests (by default in a Secret). helm history lists them; helm rollback re-applies a stored revision as a new one — rolling forward, not erasing history.
Common mistakes
- ✗Thinking
helm rollbackerases newer revisions rather than adding one - ✗Believing Helm keeps no history, so rollback needs a manual reinstall
- ✗Not knowing rendered manifests are stored per revision in the cluster
Follow-up questions
- →Where does Helm 3 store release state, and how does that differ from Helm 2?
- →What happens to
helm historynumbering right after ahelm rollback?
MiddleDebuggingOccasionalThe GitOps controller Argo CD keeps reverting a manual hotfix — diagnose
The GitOps controller Argo CD keeps reverting a manual hotfix — diagnose
This is Argo CD working as designed, not a bug. Git says replicas: 2, so the manual kubectl edit is drift, and self-heal reverts it to the Git state — editing the cluster never sticks under auto-sync self-heal. Fix it in Git: commit replicas: 6 and let Argo CD sync.
Common mistakes
- ✗Treating self-heal reverting drift as an Argo CD bug
- ✗Trying to fix desired state by editing the cluster instead of Git
- ✗Disabling self-heal as the fix rather than committing the change to Git
Follow-up questions
- →When is temporarily disabling self-heal justified, and what is the risk of doing so?
- →How would you make an emergency scale-up durable through the GitOps flow itself?
MiddleTheoryOccasionalHow does the GitOps controller Argo CD detect and reconcile drift from Git?
How does the GitOps controller Argo CD detect and reconcile drift from Git?
Argo CD holds Git's manifests as the desired state and continuously diffs them against the live cluster. When they differ the app goes OutOfSync, and a sync applies the Git state. With auto-sync self-heal, any out-of-band change is reverted, so a manual kubectl edit is undone — Git is authoritative.
Common mistakes
- ✗Thinking Argo CD writes live cluster state back into Git
- ✗Believing reconciliation only fires on a Git webhook, never continuously
- ✗Expecting a manual
kubectl editto survive under auto-sync self-heal
Follow-up questions
- →With self-heal on, why does a manual
kubectl editkeep getting reverted? - →What is the difference between
OutOfSyncandDegradedhealth in Argo CD?
MiddleCodeOccasionalRender a chart value with a default fallback in a Helm template
Render a chart value with a default fallback in a Helm template
Use Helm's default function: {{ .Values.image.tag | default .Chart.AppVersion }}. It renders .Values.image.tag when the user sets it and falls back to the chart's appVersion when empty or unset. The chart stays installable with zero overrides while still letting a user pin a tag.
Common mistakes
- ✗Piping the arguments to
defaultin the wrong order, inverting precedence - ✗Using
required, which aborts rendering instead of falling back - ✗Assuming Go templates have a
?:ternary for defaulting a value
Follow-up questions
- →How would you instead make the value mandatory, failing the render if it is unset?
- →What does
defaultreturn when.Values.image.tagis an empty string versus nil?
SeniorTheoryOccasionalPackaging tool Helm versus overlay tool Kustomize — trade-offs at scale?
Packaging tool Helm versus overlay tool Kustomize — trade-offs at scale?
Helm is a package manager: Go templating, values.yaml, chart dependencies, and versioned releases with rollback. Kustomize does simpler template-free overlays — a base plus per-env YAML patches — but no packaging, versioning, or release lifecycle. Teams combine both: Kustomize patches, Helm distributes.
Common mistakes
- ✗Calling Kustomize a templating engine rather than an overlay/patch tool
- ✗Thinking Kustomize has releases and rollback like Helm does
- ✗Believing Helm cannot vary config per environment via
values.yaml
Follow-up questions
- →Why can Kustomize overlays be easier to review in a Git diff than Helm templates?
- →How do teams combine Helm and Kustomize inside one delivery pipeline?