krikri
Version, currently 0.9.124793 versions
- 0.9.2522latestNov 8, 2026
- 0.9.2488not indexedNov 9, 2026
- 0.9.2485not indexedNov 9, 2026
- 0.9.2484not indexedNov 9, 2026
- 0.9.2479not indexedNov 9, 2026
- 0.9.2476not indexedNov 9, 2026
- 0.9.2446not indexedNov 9, 2026
- 0.9.2402not indexedNov 9, 2026
- 0.9.2391not indexedNov 9, 2026
- 0.9.2356not indexedNov 9, 2026
- 0.9.2344not indexedNov 9, 2026
- 0.9.2292Nov 3, 2026
- 0.9.2285not indexedNov 4, 2026
- 0.9.2270not indexedNov 4, 2026
- 0.9.2254not indexedNov 4, 2026
- 0.9.2209not indexedNov 4, 2026
- 0.9.2162not indexedNov 4, 2026
- 0.9.2111not indexedNov 4, 2026
- 0.9.2089Oct 29, 2026
- 0.9.2058not indexedOct 30, 2026
- 0.9.2057not indexedOct 30, 2026
- 0.9.2023not indexedOct 30, 2026
- 0.9.1973not indexedOct 30, 2026
- 0.9.1951not indexedOct 30, 2026
- 0.9.1913Oct 24, 2026
- 0.9.1880not indexedOct 24, 2026
- 0.9.1849not indexedOct 24, 2026
- 0.9.1819not indexedOct 24, 2026
- 0.9.1799not indexedOct 24, 2026
- 0.9.1786Oct 17, 2026
- 0.9.1783not indexedOct 18, 2026
- 0.9.1781not indexedOct 18, 2026
- 0.9.1770not indexedOct 18, 2026
- 0.9.1733Oct 14, 2026
- 0.9.1702not indexedOct 14, 2026
- 0.9.1661not indexedOct 14, 2026
- 0.9.1641not indexedOct 14, 2026
- 0.9.1640not indexedOct 14, 2026
- 0.9.1639not indexedOct 14, 2026
- 0.9.1638not indexedOct 14, 2026
- 0.9.1631not indexedOct 14, 2026
- 0.9.1610not indexedOct 14, 2026
- 0.9.1592not indexedOct 14, 2026
- 0.9.1567Oct 9, 2026
- 0.9.1548not indexedOct 9, 2026
- 0.9.1537not indexedOct 9, 2026
- 0.9.1516not indexedOct 9, 2026
- 0.9.1476not indexedOct 9, 2026
- 0.9.1456Oct 3, 2026
- 0.9.1423not indexedOct 4, 2026
- 0.9.1417not indexedOct 4, 2026
- 0.9.1397not indexedOct 4, 2026
- 0.9.1355not indexedOct 4, 2026
- 0.9.1348Sep 27, 2026
- 0.9.1336not indexedSep 29, 2026
- 0.9.1308not indexedSep 29, 2026
- 0.9.1283not indexedSep 29, 2026
- 0.9.1282not indexedSep 29, 2026
- 0.9.1270Sep 23, 2026
- 0.9.1256not indexedSep 24, 2026
- 0.9.1247not indexedSep 24, 2026
- 0.9.1244not indexedSep 24, 2026
- 0.9.1222not indexedSep 24, 2026
- 0.9.1189not indexedSep 24, 2026
- 0.9.1154Sep 18, 2026
- 0.9.1150not indexedSep 19, 2026
- 0.9.1143not indexedSep 19, 2026
- 0.9.1085not indexedSep 19, 2026
- 0.9.1066Sep 14, 2026
- 0.9.1020not indexedSep 14, 2026
- 0.9.1000not indexedSep 14, 2026
- 0.9.977not indexedSep 14, 2026
- 0.9.957not indexedSep 14, 2026
- 0.9.921not indexedSep 14, 2026
- 0.9.880Sep 9, 2026
- 0.9.832not indexedSep 9, 2026
- 0.9.811not indexedSep 9, 2026
- 0.9.774not indexedSep 9, 2026
- 0.9.739not indexedSep 9, 2026
- 0.9.738not indexedSep 9, 2026
- 0.9.734Sep 4, 2026
- 0.9.720not indexedSep 4, 2026
- 0.9.691not indexedSep 4, 2026
- 0.9.690not indexedSep 4, 2026
- 0.9.689not indexedSep 4, 2026
- 0.9.688not indexedSep 4, 2026
- 0.9.687not indexedSep 4, 2026
- 0.9.686not indexedSep 4, 2026
- 0.9.685not indexedSep 4, 2026
- 0.9.684not indexedSep 4, 2026
- 0.9.677not indexedSep 4, 2026
- 0.9.667not indexedSep 4, 2026
- 0.9.646Aug 31, 2026
github.com/weirdbricks/krikri
Fast, Ansible-compatible automation tool written in Crystal
Nothing has been indexed for 0.9.1247 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.
Installation
# Add this to your shard.yml
dependencies:
krikri:
github: weirdbricks/krikri
version: ~> 0.9.1247Then run:
shards installshard.yml
No shard.yml has been indexed for 0.9.1247. You can read it on the repository.
Dependencies
Unknown: the shard.yml for this version has not been read yet.
README
This README is the one indexed from the repository at its latest ref, not from the tag for this version.
krikri - Ansible-Compatible Automation Tool
A single-binary automation tool that runs Ansible playbooks - written in Crystal
π What is krikri?
krikri parses and runs standard Ansible playbook YAML directly -
the same syntax you already write, unmodified. There's no Python, no
ansible-core, no pip, and no collections directory anywhere in the
picture, on either the controller or the target - it's one compiled binary
(krikri-playbook) plus a directory of small compiled module binaries.
Three binaries ship: krikri-playbook (runs playbooks, the
ansible-playbook equivalent), krikri (ad-hoc commands, the ansible
equivalent) and krikri-lint (the ansible-lint equivalent).
| By the numbers | |
|---|---|
| Compatibility target | ansible-core 2.21.6 (byte-for-byte console output) |
| Real Galaxy roles tested on real hosts | 8,000+ (status per role) |
| Open gaps | GitHub issues |
| Deliberate scope cuts | KNOWN_MISSING.md |
| Third-party collection modules natively ported | 80 |
| Automated tests | 8,700+ passing |
Cold run vs. ansible-playbook | 2.36x faster |
Warm run vs. ansible-playbook | 7.17x faster |
| Fastest of the three benchmarked engines | 57 of 61 roles (93%) |
π How krikri differs from Ansible
What changes when you swap ansible-playbook for krikri-playbook:
| Area | Difference |
|---|---|
| Module execution | Each module is a small native binary, uploaded once and cached - no per-task Python interpreter startup or module templating. The biggest source of the speedup (see Performance). |
| Target architecture | Module binaries are compiled for the controller's CPU architecture (real Ansible ships Python modules, so it has no such constraint). A different-arch target (an x86_64 controller managing a Raspberry Pi, say) gets binaries from a plugins-<arch>/ directory next to the krikri-playbook executable when one was built there - run ./build.sh on a machine of that architecture and copy the resulting bin/plugins/ directory across as plugins-<arch>/. Without one, the run fails immediately with those instructions, before uploading anything the target could not execute. |
| SSH round trips | Consecutive tasks for the same host are batched into one round trip (--no-batching to disable). |
| Third-party collection modules | Not vendored wholesale: a community.* module runs only once ported to a native plugin (list: AVAILABLE_PLUGINS in src/krikri/module_registry.cr); anything else fails with krikri does not yet have module 'x.y.z' implemented. A role's own library/*.py modules work as usual. |
| Cloud provider modules | Out of scope, except AWS/EC2 (ec2_instance and its supporting modules, aws_ec2 inventory). |
β‘ Performance
Native compiled modules, one persistent SSH connection per host, and batched round trips make the biggest difference on idempotent re-runs - the common case for a config-management tool running on a schedule, where most tasks find nothing to change.
A 3-way benchmark against ansible-playbook and ansible-playbook
with the Mitogen strategy plugin, across a 100-role random sample, found
61 roles where all three engines produced an identical successful
outcome:
| Phase | Ansible | Ansible + Mitogen | krikri-playbook | krikri vs Ansible | krikri vs Mitogen |
|---|---|---|---|---|---|
| Cold (total) | 2176.6s | 1246.2s | 920.6s | 2.36x faster | 1.35x faster |
| Cold (median/role) | 22.04s | 11.54s | 5.32s | 3.43x faster | 1.82x faster |
| Warm (total) | 1328.0s | 598.2s | 185.3s | 7.17x faster | 3.23x faster |
| Warm (median/role) | 14.49s | 6.97s | 2.00s | 7.99x faster | 4.00x faster |
krikri-playbook was the fastest of the three engines in 57 of 61 roles (93%, see the table at the top). Full methodology and the broader 78-role set: see ansible-vs-mitogen-vs-krikri.md.
Per-role cold/warm timings: see ROLES_TESTED.md.
π Quick Start
Install via Homebrew (macOS/Linux, prebuilt binaries)
brew tap weirdbricks/krikri https://github.com/weirdbricks/krikri
brew install weirdbricks/krikri/krikri
Covers macOS (arm64/x86_64) and Linux (arm64/x86_64) - no Crystal toolchain needed. See Build from source below instead.
That default macOS install carries only macOS plugin binaries; a Mac controller managing Linux hosts fails on the first task with "no linux-x86_64 plugin binaries available". For that use the opt-in multi-arch formula, which additionally installs both Linux plugin sets (~79 MB vs ~27 MB):
brew install weirdbricks/krikri/krikri-multiarch
Build from source
Crystal is only needed to build from source (the Homebrew tap above ships
prebuilt binaries). The ssh CLI on PATH is needed for remote targets -
SSH goes through native ssh/ControlMaster, not a bundled library.
# Install dependencies
shards install
# Build (all plugins + the CLI)
./build.sh
The binaries are written to ./bin/ - add that directory to your PATH (or
prefix the commands below with ./bin/).
Example playbook
- name: Deploy app
hosts: webservers
become: true
tasks:
- name: install nginx
package:
name: nginx
state: present
- name: start nginx
service:
name: nginx
state: started
Run it against an inventory:
krikri-playbook -i inventory.ini playbook.yml
Playbook syntax is standard Ansible's - see the Ansible documentation for the full reference.
π― Command Reference
krikri-playbook playbook.yml # basic run
krikri-playbook -i inventory.ini playbook.yml # inventory
krikri-playbook --check playbook.yml # dry-run
krikri-playbook --diff playbook.yml # show file diffs
krikri-playbook -v playbook.yml # verbose
krikri-playbook -l webservers -t deploy playbook.yml # host limit / tag filter
krikri-playbook --ask-vault-pass playbook.yml # vault-encrypted playbooks/vars
krikri-playbook --no-batching playbook.yml # one SSH round trip per task
krikri-playbook --forks 10 playbook.yml # host concurrency (default: 5)
krikri-playbook --gathering smart playbook.yml # fact gathering policy
--forks defaults to 5, like ansible-playbook. A fork here is a cheap
fiber, not a forked Python interpreter, so larger values (e.g. --forks 25)
are safe and faster on big inventories; --forks 1 runs one host at a time. --gathering takes
implicit (the default, every play re-gathers), explicit (only plays
with gather_facts: true) or smart.
Callback plugins
Two callback shapes are emulated, byte-matched against ansible-core 2.21.6; anything else is a hard startup error rather than a silent divergence:
ANSIBLE_CALLBACKS_ENABLED=ansible.posix.profile_tasks(or the legacy short formprofile_tasks, comma-separated list like Ansible's) prints a wall-clock timestamp line under every TASK/RUNNING HANDLER banner and a TASKS RECAP block after PLAY RECAP ranking tasks by duration.--krikri-profile-tasksis the same switch as a flag.ANSIBLE_STDOUT_CALLBACK=oneline(oransible.builtin.oneline) replaces the whole default output surface with one line per host result (localhost | CHANGED | rc=0 | (stdout) hifor command-family results,localhost | SUCCESS => {compact json}for the rest), no banners and no PLAY RECAP - plus the deprecated callback's own[DEPRECATION WARNING](2.21.6 shape:Origin: <Config env: ANSIBLE_STDOUT_CALLBACK>and the configured spelling repeated under it).defaultis accepted as a no-op; every other stdout callback value (minimal,dense, ...) errors.
The -o / --one-line / --krikri-oneline flag turns the oneline
display on without the env var. This is a krikri extension, not
parity: real ansible-playbook rejects -o (it is adhoc-only there,
verified against 2.21.6), so accepting it cannot break an upstream
playbook command line. All krikri-only convenience switches use the
--krikri- prefix and are grouped under "Krikri-specific options:" in
--help.
Everything else - --syntax-check, --list-hosts, -e, --start-at-task,
vault subcommands and the rest - is documented in
krikri-playbook --help.
Ad-hoc commands (krikri)
krikri all -m ping
krikri webservers -a 'uptime'
krikri all -m command -a 'systemctl status nginx'
krikri all -m copy -a 'src=foo.conf dest=/etc/foo.conf' -b
krikri db -i inventory.ini -m service -a 'name=postgresql state=restarted' -b
The krikri binary is the ad-hoc counterpart of krikri-playbook (Ansible's own ansible/ansible-playbook split): one module, one run,
against a pattern of inventory hosts. It supports
-i, -m, -a, -u, -b/--become, --become-user, -C/--check,
-f/--forks, -l/--limit, -v, and its output matches Ansible's
own minimal callback style (host | SUCCESS => {...} /
host | CHANGED | rc=0 >>), not ansible-playbook's ok: [host] TASK-recap.
π Linting (krikri-lint)
krikri-lint is a from-scratch reimplementation of ansible-lint - same
rules, same output format, same exit codes, verified against ansible-lint itself
rather than against its documentation. It's static analysis only: no host
connection, no execution, no SSH.
krikri-lint playbook.yml
krikri-lint -p roles/ # parseable output
krikri-lint --fix playbook.yml # autofix the mechanically-fixable rules
krikri-lint --list-rules
See KNOWN_MISSING.md for the rules it deliberately diverges on.
β Testing
# Full minitest suite (test/ - unit, integration, lint)
scripts/minitest.sh
# Same suite on 4 parallel worker fibers (faster; tests are parallel-safe)
scripts/minitest.sh -- -p 4
# Ansible compatibility harness - runs the same playbooks through
# ansible-playbook and krikri-playbook side by side and diffs the result
crystal run compat/run.cr
See compat/README.md for what the compatibility harness covers and how it works.
For output parity specifically, scripts/output_parity.sh OUTDIR playbook.yml... runs a playbook under ansible-playbook and
krikri-playbook and diffs stdout, stderr and the exit code byte for byte
(it needs a ansible-playbook installed). The separate
krikri-playbook-generator
repo goes wider: it generates valid and deliberately mutated playbooks per
module and compares both engines on them in fresh containers.
π€ Contributing
Contributions welcome! Please:
- Review the existing code structure and KNOWN_MISSING.md
- Verify any Ansible-compatibility claims against
ansible-playbookoutput, not just documentation - Test your changes thoroughly (
scripts/minitest.sh, andcompat/run.crfor plugin behavior changes) - Submit a pull request with a clear description
π License
GNU General Public License v3.0 or later (GPL-3.0-or-later) - see LICENSE and NOTICE for details. krikri-playbook targets compatibility with Ansible, which is also GPLv3+.
π Why "krikri"?
The kri-kri (ΞΊΟΞΉ-ΞΊΟΞΉ) is the Cretan wild goat - a sturdy, agile animal native to Crete, found almost nowhere else.
π Acknowledgments
We love Ansible, and this project wouldn't have been possible without it.
krikri-playbook exists because ansible-core is genuinely great software.
The playbook/role/inventory model, the module ecosystem, and the
Jinja2-based templating that this project spends so much effort matching
are Ansible's design - the product of more than a decade of real-world use
and the work of the Ansible community and Red Hat behind it. This project
is a tribute to that design as much as it is a reimplementation of it: we
admire it enough to have rebuilt its behavior, byte for byte where it
shows, in another language.
Where krikri-playbook is faster, that's simply a different execution model
(compiled binaries vs. a Python interpreter per task) - not a knock on
Ansible, which made the choices it made for good reasons of its own.
ansible-core is, and remains, the reference implementation this project
is measured against and tries to be worthy of.
This project was built with the help of AI coding assistants (Claude Code) and other AI models: MiniMax, DeepSeek Flash, GLM 5.3 Express.
Thanks also to:
- Crystal, the language this is built with
- crinja, which krikri used
for Jinja2 templating before its own
krikri-jinja engine, and
the other Crystal shards in
shard.yml
Ansible and the Ansible logo are trademarks of Red Hat, Inc., registered in the United States and other countries. This project is not affiliated with, sponsored by, or endorsed by Red Hat, Inc. or the Ansible project.
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.9.1247- Tagged
- Sep 24, 2026
- Commit
f9efc4810160- Indexed
- not yet
Dependents
No indexed shard depends on this one yet.
Repository
github.com/weirdbricks/krikri
Metadata
- Created
- Aug 31, 2026
- Updated
- Nov 9, 2026
- Synced
- Nov 9, 2026
- Versions
- 93