tazuna state drift
Reconciles the resources recorded in the State ConfigMap against the actual objects on the live cluster, detecting resources changed by hand (live-drifted) and resources still recorded in State but removed from the live cluster (live-missing). It performs only read access to the cluster and changes nothing.
tazuna state drift [-f tazuna.yaml]
Behavior
- Load
tazuna.yaml. - For each Manifest, read the corresponding State ConfigMap (
tazuna-state-<manifest-name>in thetazunanamespace). - Fetch each resource recorded in State from the cluster by GVK / namespace / name.
- For fetched resources, recompute the ContentHash and reconcile it against the hash saved in State.
- Output non-matching ones as
live-driftedand those whose fetch itself failed (NotFound) aslive-missing.
It does not evaluate context_matches. Unlike tazuna state diff, it does not use the Build result. It only compares the hash recorded in State against the live object.
Difference from state diff
| Aspect | state diff | state drift |
|---|---|---|
| Compared against | Build result vs State | State vs live cluster |
| Cluster read | State ConfigMap only | State + each actual resource |
| What can be detected | Changes on the tazuna.yaml side | Manual kubectl apply / manual deletion |
| GenesisSecret | Always always-sync | Skips |
It helps to remember the division of labor as: state diff detects “you updated tazuna.yaml but haven’t applied it yet,” while state drift detects “you didn’t change tazuna.yaml, but someone touched the cluster.”
Output Format
When drift is found, it is output on a per-Manifest basis as follows.
Manifest: ingress-nginx
STATUS RESOURCE HASH
live-drifted ingress-nginx/apps/v1/Deployment/ingress-nginx/controller def456... (stored: abc123...)
live-missing ingress-nginx//v1/ConfigMap/ingress-nginx/extra (stored: zzz999...)
If there is no drift, only the following single line is emitted.
No drift detected.
state drift itself does not change its exit code based on whether drift exists. If you want CI to treat “drift present” as a failure, filter on whether the output does not contain No drift detected.
Skipped Manifests
The following Manifests are skipped as out of scope for drift detection.
- Manifests with an empty
name(because a State key cannot be created) type: genesissecret(by always-sync design, it re-fetches from the Provider every time, so it has no concept of drift to begin with)- Manifests whose State ConfigMap is empty or absent (never applied / synced)
Flag
No specific flags besides the global flags.
Examples
tazuna state drift
tazuna state drift -f tazuna.yaml
tazuna state drift -f tazuna.yaml --otlp-endpoint=localhost:4317
Reproduction steps with KinD
The easiest way to reproduce live-drifted locally is the following procedure.
# 1. Apply normally to create state
tazuna apply -f tazuna.yaml
# 2. Change a resource on the cluster side by hand
kubectl -n default patch deployment nginx --type=merge \
-p '{"spec":{"replicas":3}}'
# 3. drift を検知する
tazuna state drift -f tazuna.yaml
# => live-drifted エントリが 1 件出る
live-missing can be reproduced similarly by running kubectl delete by hand.
Related
- For the declared-vs-State diff, see
tazuna state diff - For how to set up drift monitoring, see Drift Monitoring
- Terminology: State / ContentHash