tazuna plan
Compares the result of Building the Manifests declared in tazuna.yaml against the state of the live cluster, and outputs, field by field, how things would change if you apply. It performs only read access to the cluster and changes nothing.
tazuna plan [-f tazuna.yaml] [--tags ...]
Behavior
- Load
tazuna.yaml. - Filter by
--tags. - Render each Manifest with its corresponding Manager’s
Build(). - Convert the rendered result into a set of
client.Objects. - Fetch each object from the cluster by GVK / namespace / name.
- Objects that could not be fetched (NotFound) are output as
+ to be created. - For objects that were fetched, output a unified diff of desired vs live, marked with
~.
Does not evaluate context_matches.
Why a client-side diff
Tazuna’s plan is implemented under the slogan of “server-side dry-run,” but the implementation is a client-side diff. This is the result of the following trade-off.
| Approach | Pros | Cons |
|---|---|---|
| server-side dry-run | Reflects admission webhooks / defaulting | The controller-runtime fake client does not fully support dry-run apply |
| client-side diff (adopted) | Reproducible in integration tests | Webhook / defaulting results are not visible |
Understand it as choosing “a plan that can be tested” even at some cost to accuracy. Fields rewritten by an admission webhook (mutation) and server-side defaulting are not reflected in the plan output.
Output Format
Manifest: nginx
+ Deployment/default/nginx-new (to be created)
~ ConfigMap/default/nginx-conf
spec:
replicas: 1
+ replicas: 3
Manifest: cert-manager
+ Issuer/cert-manager/letsencrypt-prod (to be created)
+ <Kind/ns/name> (to be created)— a resource that does not yet exist on the live cluster~ <Kind/ns/name>— a resource that exists but has field differences. The indented unified diff fromk8s.io/apimachinery/pkg/util/diff.Difffollows directly below.
If there are no differences, only the single line No changes detected. is emitted.
Fields excluded when computing the diff
To avoid noise, the following fields are stripped before comparing live and desired.
metadata.resourceVersion/uid/generationmetadata.managedFieldsmetadata.creationTimestamp/selfLinkstatus
Skipped Manifests
- Manifests with an empty
name type: genesissecret(being always-sync, it does not fit the concept of a field diff in plan)
Flag
In addition to global flags, the following are accepted.
| Flag | Alias | Type | Default | Description |
|---|---|---|---|---|
--tags | -t | []string | [] | Limits the plan target to Manifests carrying at least one of the specified tags (OR evaluation). |
Examples
tazuna plan
tazuna plan -f tazuna.yaml
tazuna plan -f tazuna.yaml --tags web,batch
tazuna plan -f tazuna.yaml --otlp-endpoint=localhost:4317
Related
- To actually apply, see
tazuna apply - For State-based diffs, see
tazuna state diff - For detecting manual changes, see
tazuna state drift