Argo CD / Automation, lifecycle, and trust / Lesson 10
Custom resource health as a versioned contract
Interpret status conditions and observed generation without making missing evidence healthy.
On this page
Lesson goals
- Explain the role and limits of custom Lua health assessment.
- Design fixtures for stale, missing, progressing, and explicitly failed observations.
A custom kind needs domain meaning
A custom resource can expose status fields whose meaning belongs to its controller and API version. Argo CD cannot infer every business readiness contract from a field named Ready. ParcelPolicy is a synthetic kind whose controller is assumed to publish observedGeneration and a ready boolean for this lesson only. Real conditions may have different names, states, reasons, and transition rules. Review the actual CRD and controller documentation before writing health logic. A generic always-Healthy rule hides uncertainty and can release dependent work before the required state exists.
Current intent and old observations can differ
metadata.generation can identify a desired-spec generation, while a controller may report which generation its status reflects. A ready observation for an older generation may describe yesterday’s intent. The exact contract is kind-specific; do not assume every API implements observedGeneration identically. Missing status, delayed reconciliation, explicit failure, and successful current reconciliation need distinct handling. Health assessment should be bounded and should not query external systems or perform mutation as a side effect of merely reading status.
Read a limited illustrative health function
The Lua snippet below returns Progressing until the synthetic current-generation contract is met, then Healthy when ready is true. It is not installed in Argo CD and does not define a universal custom-resource policy. Release-3.1 custom checks receive obj and return supported status and optional message fields under documented configuration. Standard-library access is restricted by default under that model. Enabling broader libraries is not a prerequisite for this simple field check and should not be used as an indiscriminate fix.
local hs = { status = "Progressing", message = "Awaiting current observation" }
if obj.status ~= nil and obj.metadata ~= nil then
if obj.status.observedGeneration == obj.metadata.generation then
if obj.status.ready == true then
hs.status = "Healthy"
hs.message = "Current synthetic readiness observed"
end
end
end
return hs
This is specific to the declared synthetic fields and is not executed or configured. A real kind needs explicit failure and missing-generation decisions and representative fixtures; the snippet is not a complete general health customization.
Test one invariant in a separate local model
The complete Python model below rejects stale and absent observations before accepting current readiness. It models a declared invariant, not Lua evaluation, Argo CD aggregation, or Kubernetes controller behavior. Passing these cases does not prove that the Lua snippet is correct for a real CRD. Actual customization tests need the supported platform or project tooling in a separately authorized suitable environment. Retain fixtures for explicit failure, no status, old generation, false readiness, and current true readiness so future controller changes cannot silently weaken the contract.
def ready(generation, status):
return bool(status is not None and status.get("observedGeneration") == generation and status.get("ready") is True)
print(ready(4, None))
print(ready(4, {"observedGeneration": 3, "ready": True}))
print(ready(4, {"observedGeneration": 4, "ready": True}))
False
False
True
Only local dictionaries are evaluated. This does not execute Lua, validate an Argo CD customization, or observe a custom controller.
Health rules can change release behavior
A health customization can override existing assessment and influence later waves or application summaries. Treat its source and configuration as reviewed delivery code. Keep status messages useful and free of sensitive payloads. Avoid a massive wildcard script that guesses many unrelated kinds. If a controller changes its API or condition semantics, review the health rule and fixtures together. User-level verification still remains separate: even correct resource readiness may not establish that label creation and external carrier behavior satisfy the release promise.
Common errors and fixes
Missing custom status is returned as Healthy.
- Why it happens
- Absence of failure was confused with positive current evidence.
- How to fix it
- Represent waiting or unknown behavior explicitly under the supported health contract.
- Prevent it next time
- Test missing, stale, false, and failed observations.
A Ready result from an older generation permits dependent work.
- Why it happens
- Observation freshness was omitted from the kind’s declared readiness rule.
- How to fix it
- Check the controller’s generation contract before accepting readiness.
- Prevent it next time
- Version fixtures with CRD and controller semantics.
One wildcard health script assumes every custom kind has identical fields.
- Why it happens
- Different APIs are collapsed into an unverified universal rule.
- How to fix it
- Use small kind-specific reviewed logic and representative fixtures.
- Prevent it next time
- Assign ownership and review override scope.
Check your understanding
1. The synthetic status says ready=true for generation three while metadata generation is four. What does the local model decide?
Show worked solution
It returns false because the observation does not describe current intent. This is the declared synthetic rule, not a universal Kubernetes condition rule. Inspect the actual controller’s contract before applying equivalent logic to a real kind.
2. Does a passing Python invariant test establish a successful Lua customization on Argo CD?
Show worked solution
No. It verifies only the local Python behavior and expected values. Lua syntax, supported configuration, aggregation, and actual controller status need their own appropriate authorized validation. Keep the evidence claim at the level actually tested.
Key takeaways
- Health depends on kind-specific current evidence.
- Custom health logic is reviewed delivery behavior, not cosmetic status formatting.