janus

module
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2026 License: Apache-2.0

README

Janus

Atomic changes across Kubernetes resources.

Janus groups resource mutations across multiple Kubernetes namespaces into a single transaction. Create, Update, Patch, or Delete — each step is paired with an automatic compensating action. If any step fails, everything rolls back.

Patch operations use Server-Side Apply, so Janus owns only the fields it touches. This composes cleanly with GitOps tools — ArgoCD and Flux keep ownership of their fields on the same resources.

Example

# Create a transaction
janus create db-migration --sa janus-ops

# Patch connection strings across namespaces
janus add db-migration --type Patch --target ConfigMap/app-config --target-ns frontend \
  -f connection-patch.yaml
janus add db-migration --type Patch --target ConfigMap/app-config --target-ns backend \
  -f connection-patch.yaml --order 1
janus add db-migration --type Patch --target Deployment/api-server --target-ns backend \
  -f env-patch.yaml --order 2

# Seal to begin processing
janus seal db-migration

If the Deployment patch fails, both ConfigMap patches are automatically reverted. Each resource's prior field values are captured before mutation and restored on rollback.

kubectl get transaction db-migration
NAME            PHASE       SEALED   AGE
db-migration    Committed   true     34s

How it works

Janus implements the Saga pattern — each resource mutation is paired with a compensating action derived automatically from the prior state. If the sequence fails at step n, steps n-1 through 1 are undone in reverse order.

Two CRDs:

  • Transaction — groups changes under a common identity, controls when processing begins (spec.sealed), and tracks progress.
  • ResourceChange — a single mutation (Create, Update, Patch, or Delete) owned by a Transaction.

Patch operations use Server-Side Apply with a field manager scoped to the transaction. This means Janus owns only the fields it touches — other controllers and GitOps tools retain ownership of their fields on the same resources.

Resources are locked via advisory Kubernetes Leases during the transaction. Locks prevent concurrent Janus transactions from colliding but do not block direct kubectl writes — this is a deliberate trade-off to avoid admission webhook overhead.

Operations execute under a user-specified ServiceAccount identity, so RBAC boundaries are enforced per transaction.

When to use this

Operational changes that span multiple resources or namespaces, where the intermediate state is dangerous and GitOps doesn't apply:

  • Cross-resource field patches — update connection strings in 3 ConfigMaps and an env var in 2 Deployments as one unit; rollback all if any fails
  • Cross-namespace coordination — tenant provisioning, service mesh config, or infrastructure changes that cross namespace boundaries
  • Operational changes outside GitOps — incident response, migrations, or infrastructure changes that aren't templated manifests in a repo
  • Security-sensitive intermediate states — Namespace + RBAC + NetworkPolicy where a partial apply creates an unprotected window

When not to use this

  • Single-resource changes — just use kubectl apply.
  • Standard deployments — if your changes are templated manifests in git, use Helm, ArgoCD, or Flux. Janus is for operational changes that live outside the GitOps lifecycle.
  • Workflow orchestration — Janus applies resource mutations, not arbitrary jobs. Use Argo Workflows or Tekton for DAGs.
  • Workloads where eventual consistency is acceptable — standard Kubernetes reconciliation is simpler and more idiomatic.

Install

Prerequisites
  • Kubernetes v1.30+
  • kubectl v1.30+
  • cert-manager (for webhook TLS)
Helm
helm install janus chart/ --namespace janus-system --create-namespace
Container image

Pre-built multi-arch images (amd64 + arm64) are published to ghcr.io/aalpar/janus on every release.

Kustomize
make install
make deploy IMG=ghcr.io/aalpar/janus:<version>
Install the CLI
go install github.com/aalpar/janus/cmd/janus@latest

Or download a binary from the Releases page.

Set up a ServiceAccount

Janus runs resource operations under a ServiceAccount you specify. Create one with permissions on the resources your transactions will touch:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: janus-ops
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: janus-ops-edit
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: edit
subjects:
- kind: ServiceAccount
  name: janus-ops
  namespace: default

Documentation

  • Tutorial — hands-on walkthrough: create, rollback, and recover transactions using both the CLI and kubectl.
  • User Guide — complete reference: change types, ordering, monitoring, failure handling, recovery.
  • Design — architecture, state machine, lock manager, rollback storage, reconciliation loop.
  • Invariants — safety and liveness guarantees.
  • Contributing — how to build, test, and submit changes.
  • Bibliography — annotated references on Sagas, two-phase commit, and crash recovery.

License

Apache License 2.0 — see LICENSE.

Directories

Path Synopsis
api
v1alpha1
Package v1alpha1 contains API Schema definitions for the tx v1alpha1 API group.
Package v1alpha1 contains API Schema definitions for the tx v1alpha1 API group.
cmd
controller command
janus command
internal
metrics
Package metrics defines Prometheus metrics for the Janus transaction controller.
Package metrics defines Prometheus metrics for the Janus transaction controller.
recover
Package recover implements offline recovery for failed or interrupted Janus transactions by reading rollback state from ConfigMaps.
Package recover implements offline recovery for failed or interrupted Janus transactions by reading rollback state from ConfigMaps.
rollback
Package rollback defines the rollback ConfigMap contract shared between the controller and the recover CLI.
Package rollback defines the rollback ConfigMap contract shared between the controller and the recover CLI.
test

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL