katomik - Atomic Apply for Kubernetes Manifests with Rollback Support. katomik Applies multiple Kubernetes manifests with all-or-nothing guarantees. Like kubectl apply -f, but transactional:if any resource fails to apply or become ready, all previously applied resources are rolled back automatically. all-or-nothing kubectl apply -f GitHub Repo → GitHub Repo → GitHub Repo → Features Atomic behavior: Applies multiple manifests as a unit. If anything fails, restores the original state. Server-Side Apply (SSA): Uses PATCH with SSA to minimize conflicts and preserve intent. Status tracking: Waits for all resources to become Current (Ready/Available) before succeeding. Rollback support: Automatically restores previous state if apply or wait fails. Recursive: Like kubectl, supports directories and -R for recursive traversal. STDIN support: Use -f - to read from stdin. Atomic behavior: Applies multiple manifests as a unit. If anything fails, restores the original state. Atomic behavior Server-Side Apply (SSA): Uses PATCH with SSA to minimize conflicts and preserve intent. Server-Side Apply PATCH Status tracking: Waits for all resources to become Current (Ready/Available) before succeeding. Status tracking Current Rollback support: Automatically restores previous state if apply or wait fails. Rollback support Recursive: Like kubectl, supports directories and -R for recursive traversal. Recursive kubectl -R STDIN support: Use -f - to read from stdin. STDIN support -f - stdin Installation Manual Installation Download the latest binary for your platform from the Releases page. Place the binary in your system's PATH (e.g., /usr/local/bin). Download the latest binary for your platform from the Releases page. Releases page Releases page Place the binary in your system's PATH (e.g., /usr/local/bin). PATH /usr/local/bin Installation script ( set -euo pipefail OS="$(uname | tr '[:upper:]' '[:lower:]')" ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" TAG="$(curl -s https://api.github.com/repos/hashmap-kz/katomik/releases/latest | jq -r .tag_name)" curl -L "https://github.com/hashmap-kz/katomik/releases/download/${TAG}/katomik_${TAG}_${OS}_${ARCH}.tar.gz" | tar -xzf - -C /usr/local/bin && \ chmod +x /usr/local/bin/katomik ) ( set -euo pipefail OS="$(uname | tr '[:upper:]' '[:lower:]')" ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" TAG="$(curl -s https://api.github.com/repos/hashmap-kz/katomik/releases/latest | jq -r .tag_name)" curl -L "https://github.com/hashmap-kz/katomik/releases/download/${TAG}/katomik_${TAG}_${OS}_${ARCH}.tar.gz" | tar -xzf - -C /usr/local/bin && \ chmod +x /usr/local/bin/katomik ) Homebrew installation brew tap hashmap-kz/homebrew-tap brew install katomik brew tap hashmap-kz/homebrew-tap brew install katomik Usage # Apply multiple files atomically katomik apply -f manifests/ # Read from stdin katomik apply -f - < all.yaml # Apply recursively katomik apply -R -f ./deploy/ # Set a custom timeout (default: 5m) katomik apply --timeout 2m -f ./manifests/ # Process and apply a manifest located on a remote server katomik apply \ -f https://raw.githubusercontent.com/user/repo/refs/heads/master/manifests/deployment.yaml # Apply multiple files atomically katomik apply -f manifests/ # Read from stdin katomik apply -f - < all.yaml # Apply recursively katomik apply -R -f ./deploy/ # Set a custom timeout (default: 5m) katomik apply --timeout 2m -f ./manifests/ # Process and apply a manifest located on a remote server katomik apply \ -f https://raw.githubusercontent.com/user/repo/refs/heads/master/manifests/deployment.yaml Example Output # katomik apply -f test/integration/k8s/manifests/ + waiting for resources | namespace/katomik-test (cluster) | configmap/postgresql-init-script katomik-test | configmap/postgresql-envs katomik-test | configmap/postgresql-conf katomik-test | service/postgres katomik-test | persistentvolumeclaim/postgres-data katomik-test | statefulset/postgres katomik-test | configmap/prometheus-config katomik-test | persistentvolumeclaim/prometheus-data katomik-test | service/prometheus katomik-test | statefulset/prometheus katomik-test | persistentvolumeclaim/grafana-data katomik-test | service/grafana katomik-test | configmap/grafana-datasources katomik-test | deployment/grafana katomik-test + waiting for resources + watching | Service/grafana katomik-test Unknown | Deployment/grafana katomik-test Unknown | StatefulSet/postgres katomik-test InProgress | StatefulSet/prometheus katomik-test InProgress + watching ✓ Success # katomik apply -f test/integration/k8s/manifests/ + waiting for resources | namespace/katomik-test (cluster) | configmap/postgresql-init-script katomik-test | configmap/postgresql-envs katomik-test | configmap/postgresql-conf katomik-test | service/postgres katomik-test | persistentvolumeclaim/postgres-data katomik-test | statefulset/postgres katomik-test | configmap/prometheus-config katomik-test | persistentvolumeclaim/prometheus-data katomik-test | service/prometheus katomik-test | statefulset/prometheus katomik-test | persistentvolumeclaim/grafana-data katomik-test | service/grafana katomik-test | configmap/grafana-datasources katomik-test | deployment/grafana katomik-test + waiting for resources + watching | Service/grafana katomik-test Unknown | Deployment/grafana katomik-test Unknown | StatefulSet/postgres katomik-test InProgress | StatefulSet/prometheus katomik-test InProgress + watching ✓ Success 🔒 Rollback Guarantees On failure (bad manifest, missing dependency, timeout, etc.): Existing objects are reverted to their exact pre-apply state. New objects are deleted. Existing objects are reverted to their exact pre-apply state. New objects are deleted. This guarantees your cluster remains consistent - no partial updates. Feedback Have a feature request or issue? Feel free to __open an issue __or submit a PR! open an issue