Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

  1. Load tazuna.yaml.
  2. For each Manifest, read the corresponding State ConfigMap (tazuna-state-<manifest-name> in the tazuna namespace).
  3. Fetch each resource recorded in State from the cluster by GVK / namespace / name.
  4. For fetched resources, recompute the ContentHash and reconcile it against the hash saved in State.
  5. Output non-matching ones as live-drifted and those whose fetch itself failed (NotFound) as live-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

Aspectstate diffstate drift
Compared againstBuild result vs StateState vs live cluster
Cluster readState ConfigMap onlyState + each actual resource
What can be detectedChanges on the tazuna.yaml sideManual kubectl apply / manual deletion
GenesisSecretAlways always-syncSkips

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.