Helm / Basic: chart and rendering foundations / Lesson 3
Values precedence and type preservation
Resolve layered values deliberately and distinguish an absent field, a false value, a replaced list and a removed default key.
On this page
Lesson goals
- Explain ordered values sources and the effect of repeated overrides.
- Preserve strings, numbers and booleans through YAML and templates.
- Diagnose map merging and list replacement without assuming append behavior.
Name the layers
Defaults are the beginning of a values contract, not the final input. A parent can supply subchart values; user files override chart defaults; command-line assignments have higher specificity. With multiple values files, order matters, and a later file can replace an earlier decision. Record the ordered inputs, not merely the file names. In an environment review, a stale wrapper script can append a flag after the reviewed file and change the result. Prefer a small set of versioned files over undocumented command histories when several people must reproduce the same render.
Reason about shape before values
Helm coalescing merges maps, while arrays are generally replaced rather than appended. A list of two containers is one value, not a keyed registry that automatically merges by container name. Null can remove a default key during merging, which matters when selecting mutually exclusive probe handlers. Changing a map into a string can break a template expecting nested fields. Review both the data shape and its contents. The illustrative layers below leave service.port at 8080, replace the zones list with west only and remove the default probe handler before a different handler is introduced.
# defaults
service:
port: 8080
zones: [east, central]
probe:
httpGet:
path: /ready
port: 8080
---
# later values file
zones: [west]
probe:
httpGet: null
tcpSocket:
port: 8080
These are separate layer examples, not one values file to submit. The intended merged probe has only tcpSocket.
Preserve scalar types
A value such as an account label or numeric-looking identifier may need to remain a string even when it contains digits. Quote such values in YAML and quote string-valued output in the template. Keep integer fields such as service ports numeric where the Kubernetes schema requires an integer. A string flag "false" is not the boolean false, and both differ from a missing key. Command-line parsing adds another opportunity for coercion; documented string-specific options can be appropriate in a real workflow, but versioned values files make intended types easier to review together.
Make false and zero visible
The template default function treats several empty values, including false and zero, as empty. That behavior is useful for an optional display label but dangerous when zero replicas is an intentional decision. Use a schema and explicit presence checks when absence and zero carry different meanings. The Python example models that distinction with a membership test. It does not reproduce all Helm merge rules. Its narrow purpose is to show why truthiness cannot answer whether a user supplied a key. Decide the documented behavior for absent, null and zero separately before writing a fallback.
values = {"replicaCount": 0, "enabled": False}
replicas = values["replicaCount"] if "replicaCount" in values else 1
print(replicas)
print(type(values["enabled"]).__name__)
0
bool
The complete program preserves intentional zero and confirms that enabled is boolean. It is an input-contract model only.
Review the effective contract
When an unexpected value appears, inspect the source defaults, parent scope, ordered user files and final assignments before editing templates. Compare the effective value with the expression that consumes it: a correct value under the wrong key remains unused. Avoid placing secrets in a diagnostic dump because computed values can contain sensitive inputs. Use synthetic excerpts that preserve types and paths. A durable fix removes a conflicting input or corrects the documented contract; adding another unexplained override only makes the next review harder. Include list replacement and zero-value cases in the review matrix.
Common errors and fixes
A list override unexpectedly removes earlier entries
- Why it happens
- The author expected list append semantics during coalescing.
- How to fix it
- Provide the complete desired list or redesign the input as a documented map when keyed merging is appropriate.
- Prevent it next time
- Show list replacement explicitly in values examples.
replicaCount zero becomes one
- Why it happens
- A default expression treated zero as empty.
- How to fix it
- Use an explicit presence contract and validate the allowed numeric range.
- Prevent it next time
- Review absent, null and zero as distinct cases.
Both httpGet and tcpSocket appear in one probe
- Why it happens
- A map merge retained the default handler while adding another.
- How to fix it
- Remove the unused handler explicitly with the chart-supported null override.
- Prevent it next time
- Validate mutually exclusive alternatives through schema and render cases.
Check your understanding
1. Defaults contain zones [east, central]; a later file contains [west]. What should the reviewer expect?
Show worked solution
Expect the later list [west], not a three-item union. Check whether removing east and central changes application placement or merely descriptive metadata, because the surrounding template decides the consequence. If all zones are intended, write all three explicitly in the final layer and document why that layer owns the complete list.
2. An account code is 0017 and a port is 8080. How should their contracts differ?
Show worked solution
The account code is a string whose leading zeros matter, so quote it in values and string output. The port is an integer constrained to the intended range, so preserve a numeric YAML value and numeric output. A schema can reject the wrong types early. Quoting every output indiscriminately would damage the port contract rather than improve safety.
Key takeaways
- Ordered inputs, data shapes and scalar types jointly determine values behavior.
- Presence checks protect intentional false and zero values.