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

Internal Structure of State

State is the record Tazuna uses to track “resources I installed.” It is stored in ConfigMaps inside the cluster and is the starting point for tazuna state list / tazuna state diff / tazuna state sync.

This page covers the storage format of State and the spec of State key / ContentHash / Diff type that support it.

Storage Location

State is stored inside the cluster. Tazuna does not use local files or remote storage.

ElementValue
Namespacetazuna (auto-created if absent)
ConfigMap nametazuna-state-<manifest-name>
FormatOne entry per resource as a key/value pair in ConfigMap.data

One Manifest corresponds to one ConfigMap. Since each Manifest’s name after includes expansion is unique (see tazuna.yaml’s name), ConfigMap names do not collide.

State key

A State key is the identifier of a single entry inside a ConfigMap. As a struct it carries manifestName / group / version / kind / namespace / name; its string format comes in two variants.

Resource scopeFormatNumber of parts
namespaced{manifest}/{group}/{version}/{kind}/{namespace}/{name}6
cluster-scoped{manifest}/{group}/{version}/{kind}/{name}5

group is an empty segment for the core group (""). For example, a core/v1 ConfigMap (namespaced) is written like my-manifest//v1/ConfigMap/default/my-cm, with the gap between the second and third slashes empty.

Encoding to ConfigMap data Key

Kubernetes ConfigMap.data keys only allow [-._a-zA-Z0-9]+ and cannot contain /. To work around this, Tazuna replaces / in the State key string with __ when writing to the ConfigMap, and reverses the substitution on read.

state key:    nginx/apps/v1/Deployment/default/nginx
data key:     nginx__apps__v1__Deployment__default__nginx

Since the Kubernetes DNS-1123 names (manifest name / group / namespace / name) do not contain _, __ works safely as a separator.

State Entry (StateEntry)

Each entry is written into one value in the ConfigMap as the following JSON form.

{"contentHash":"<hex sha256>"}
FieldTypeDescription
contentHashstringThe SHA-256 hash of the resource’s contents. See ContentHash for details.

_metadata Key

ConfigMaps also contain one more reserved key, _metadata. This is not a State entry but metadata for the State as a whole.

{"gitCommitHash":"<sha>","lastSyncedAt":"<rfc3339>"}
FieldTypeDescription
gitCommitHashstringThe git commit hash recorded at sync time.
lastSyncedAtstringSync timestamp.

_metadata cannot be used for a Manifest name (it is treated as a reserved word in tazuna.yaml’s name). This is a guard against the collision.

ContentHash

ContentHash is a SHA-256 hex string computed from each resource’s YAML representation. Tazuna computes it after stripping server-side-assigned fields and status.

Excluded fields:

FieldReason for exclusion
metadata.resourceVersionUsed for cluster generation tracking; changes on every apply
metadata.uidAssigned by the cluster; changes on every apply
metadata.creationTimestampAssigned by the cluster; changes on every apply
metadata.generationAssigned by the cluster; changes on every apply
metadata.managedFieldsServer-side apply tracking information
metadata.selfLinkAssigned by the cluster
statusDynamic field written by controllers

Computation procedure:

  1. Deep-copy the object via JSON marshal / unmarshal.
  2. Remove the excluded fields above.
  3. JSON-marshal the rest.
  4. Take SHA-256 and convert to a hex string.

Including status would change the hash on every Pod restart, so we narrow it down to the granularity “is this the same state as expressed by tazuna.yaml.”

Diff type

tazuna state diff and tazuna state sync classify the comparison between the Build result and existing State by Diff type.

Diff typeMeaningstate sync behavior
addedPresent in the Build result, absent from StateApply
modifiedPresent in both, but with different ContentHashApply
removedPresent in State, absent from the Build resultSkipped by default. Deleted only when TAZUNA_STATE_SYNC_DELETE=true
always-syncSkip diff computation; always treat as a sync targetApply

state diff output is stably sorted in the order addedmodifiedremovedalways-sync, with State keys ascending within each Diff type.

always-sync Targets

In the current version, Secrets derived from type: genesissecret are classified as always-sync. These have the Provider side as the source of truth and are synchronized every time; they are not targets of ContentHash-based diffing. See GenesisSecret schema - State and always-sync for details.