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.
| Element | Value |
|---|---|
| Namespace | tazuna (auto-created if absent) |
| ConfigMap name | tazuna-state-<manifest-name> |
| Format | One 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 scope | Format | Number 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>"}
| Field | Type | Description |
|---|---|---|
contentHash | string | The 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>"}
| Field | Type | Description |
|---|---|---|
gitCommitHash | string | The git commit hash recorded at sync time. |
lastSyncedAt | string | Sync 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:
| Field | Reason for exclusion |
|---|---|
metadata.resourceVersion | Used for cluster generation tracking; changes on every apply |
metadata.uid | Assigned by the cluster; changes on every apply |
metadata.creationTimestamp | Assigned by the cluster; changes on every apply |
metadata.generation | Assigned by the cluster; changes on every apply |
metadata.managedFields | Server-side apply tracking information |
metadata.selfLink | Assigned by the cluster |
status | Dynamic field written by controllers |
Computation procedure:
- Deep-copy the object via JSON marshal / unmarshal.
- Remove the excluded fields above.
- JSON-marshal the rest.
- 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 type | Meaning | state sync behavior |
|---|---|---|
added | Present in the Build result, absent from State | Apply |
modified | Present in both, but with different ContentHash | Apply |
removed | Present in State, absent from the Build result | Skipped by default. Deleted only when TAZUNA_STATE_SYNC_DELETE=true |
always-sync | Skip diff computation; always treat as a sync target | Apply |
state diff output is stably sorted in the order added → modified → removed → always-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.
Related
- CLIs that operate on it:
tazuna state list/tazuna state diff/tazuna state sync - Terminology: State / State key / ContentHash / Diff type / always-sync