krikri
Version, currently 0.9.92129 versions
- 0.9.1154latestSep 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.921 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.921Then run:
shards installshard.yml
No shard.yml has been indexed for 0.9.921. 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 real Ansible playbooks - written in Crystal
π What this is
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.
It is not a new automation DSL you have to learn, and not a "mostly
compatible" reimplementation verified by eyeballing docs - every plugin's
behavior is checked against real ansible-playbook output on real hosts,
across 1,809 real Galaxy roles tested to date (see
ROLES_TESTED.md; Differences and What's missing
below), and a Docker-based compatibility harness (compat/) runs the same
playbooks through both engines side by side and diffs the resulting
state. Any observed
divergence from real Ansible's behavior is treated as a bug in this
project, not a documented limitation, unless it's one of the deliberate
structural exclusions called out below.
π How this differs from real (Python) Ansible
If you already know Ansible, here's what actually changes when you swap
ansible-playbook for ./bin/krikri-playbook:
Architecture: compiled binaries, not a Python interpreter per task
Real Ansible ships a Python module's source, templates it, and starts a
fresh Python interpreter for it on the target host for every single
task, every run - even when nothing changes. krikri compiles
each module (apt, copy, service, ...) into its own small native
binary once; running a task means uploading that binary (cached after the
first run) and executing it directly - no interpreter startup, no module
templating step, no AnsiballZ wrapper. Consecutive tasks bound for the
same host are also batched into a single SSH round trip by default
(--no-batching to disable) instead of one round trip per task.
This is the single biggest practical difference, and it shows up directly in wall-clock time - see Performance below.
What's structurally different (by design, not a gap)
Third-party COLLECTION Python modules aren't reimplemented wholesale -
this project doesn't ship or vendor a collections directory, so a
community.*/bodsch.*/etc. module only runs if it's been natively
ported into a compiled plugin binary (a role's OWN private library/*.py
module is unaffected either way - that always runs fine, delegated to the
target's real python3). But that porting isn't hypothetical or "not our
problem": every one of the 1,809+ real Galaxy roles this project is
benchmarked against (see How this differs above) surfaces whichever
third-party modules that role's own tasks actually call, and the ones
that show up often enough get natively ported the same way an
ansible.builtin gap does - found via a real role hitting it, fixed,
verified against real ansible-playbook output. 62 third-party
collection modules are natively ported as of this writing - the most
common community.general/community.docker/community.crypto/
community.mysql/community.rabbitmq modules real-world roles reach
for (docker_container, docker_image, archive, ufw, htpasswd,
openssl_csr, mysql_db, and more - see AVAILABLE_PLUGINS in
src/krikri/playbook_parser.cr for the current full list). A module
outside that set still hard-stops cleanly ("krikri does not yet have module 'x.y.z' implemented", see What's missing below) rather than
silently skipping - the gap is real, but it shrinks by usage frequency,
not by chasing collection completeness for its own sake.
Cloud provider modules are a genuine, deliberate structural exclusion
for every provider except AWS/EC2, which is fully supported as of
this writing: ec2_instance plus the minimum cluster needed to actually
use it - ec2_key, ec2_security_group, ec2_vpc_net_info,
ec2_vpc_subnet_info, ec2_ami_info (all real, signed EC2 Query API
calls, not stubs) - alongside the pre-existing ec2_metadata_facts.
Other providers' resource-management modules (azure_rm_*, GCP, etc.)
remain out of scope - these model an entire cloud provider's API surface
rather than a single host-local operation, and AWS/EC2 was a deliberate,
scoped exception rather than an opening of that whole category. Cloud
inventory plugins are a similar partial exception: aws_ec2 is
implemented (real signed EC2 API calls), alongside
host_list/ini/yaml/constructed; other providers' inventory
plugins (azure, gcp, openstack, ...) are not. See What's missing
below.
β What's missing
Gaps here are found by running real production Ansible roles (from Galaxy) against both engines on real hosts and diffing the result, not from a pre-planned feature checklist:
- KNOWN_MISSING.md - the current, short, up-to-date list of any open real gaps plus the full explicit scope-cut list (cloud modules, role-private modules, a handful of untestable/ narrow module gaps, etc., each with the reasoning behind it).
- ROLES_TESTED.md - the current status of every real Ansible Galaxy role that's been benchmarked against a live host, one line each, so you can check whether something resembling your own playbooks has already been exercised.
β‘ 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 but Python still pays a fresh interpreter-and-module cost per task regardless.
A 3-way benchmark against real 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 | real 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%). 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 & Run below to build from source instead.
Prerequisites
- Crystal (tested with 1.21.x - see
shard.ymlfor the declared minimum) (install guide) - The
sshCLI onPATHfor remote targets (SSH connections use nativessh/ControlMasterunder the hood, not a bundled library)
Build & Run
# Install dependencies
shards install
# Build (all plugins + the CLI)
./build.sh
# Run a playbook
./bin/krikri-playbook playbook.yml
# With options
./bin/krikri-playbook --check --diff -i inventory.ini playbook.yml
π Project Structure
krikri-playbook/
βββ krikri-playbook.cr # CLI entry point
βββ src/krikri/ # Engine: parser, task executor, SSH,
β # inventory, roles, loops, vault, facts
βββ plugins/ # One binary per Ansible module
βββ spec/ # crystal spec unit + integration tests
βββ compat/ # Docker-based real-ansible-playbook
β # compatibility harness
βββ testing/ # Manual smoke-test fixture playbooks
βββ build.sh # Build script (all plugins + CLI)
βββ shard.yml # Dependencies
Go to plugins/ to see the implemented plugins.
π‘ Usage Example
- name: Deploy app
hosts: webservers
become: true
tasks:
- name: install nginx
package:
name: nginx
state: present
- name: start nginx
service:
name: nginx
state: started
notify: reload nginx
handlers:
- name: reload nginx
service:
name: nginx
state: reloaded
Supports standard Ansible playbook syntax. See the Ansible documentation for playbook reference.
π― Command Reference
# Basic usage
./bin/krikri-playbook playbook.yml
# With inventory
./bin/krikri-playbook -i inventory.ini playbook.yml
# Dry-run (check mode)
./bin/krikri-playbook --check playbook.yml
# Show changes
./bin/krikri-playbook --diff playbook.yml
# Verbose output
./bin/krikri-playbook -v playbook.yml
# Limit to a host group/pattern, run only tagged tasks
./bin/krikri-playbook -l webservers -t deploy playbook.yml
# Vault-encrypted playbook/vars
./bin/krikri-playbook --ask-vault-pass playbook.yml
./bin/krikri-playbook --vault-password-file pass.txt playbook.yml
# Disable task batching (on by default - see Performance above)
./bin/krikri-playbook --no-batching -i inventory.ini playbook.yml
# Run each task against up to 10 hosts concurrently (default: 5, matching
# ansible-playbook; --forks 1 restores one-host-at-a-time)
./bin/krikri-playbook --forks 10 -i inventory.ini playbook.yml
# Fact gathering policy (default: implicit, matching ansible-playbook):
# implicit - every play re-gathers
# explicit - only plays that set gather_facts: true
# smart - each host gathered at most once per run
# Under smart, add `meta: clear_facts` to a play (e.g. after a reboot or a
# package install) to force the next play to gather again.
./bin/krikri-playbook --gathering smart -i inventory.ini playbook.yml
# Multiple options
./bin/krikri-playbook --check --diff -i production.ini playbook.yml
Ad-hoc commands (krikri)
A separate binary, matching real Ansible's own ansible/ansible-playbook
split - runs exactly one module against a pattern of inventory hosts,
reusing the same connection/become/check-mode/forks engine as the
playbook runner:
./bin/krikri all -m ping
./bin/krikri webservers -a 'uptime'
./bin/krikri all -m command -a 'systemctl status nginx'
./bin/krikri all -m copy -a 'src=foo.conf dest=/etc/foo.conf' -b
./bin/krikri db -i inventory.ini -m service -a 'name=postgresql state=restarted' -b
Supports -i, -m, -a, -u, -b/--become, --become-user, -C/--check,
-f/--forks, -l/--limit, -v. Output matches real ansible's own
minimal callback (host | SUCCESS => {...} / host | CHANGED | rc=0 >>),
not ansible-playbook's ok: [host] TASK-recap style.
β Testing
# Unit + integration specs (crystal spec's own test runner)
crystal spec
# Ansible compatibility harness - runs the same playbooks through real
# 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.
π€ Contributing
Contributions welcome! Please:
- Review the existing code structure and KNOWN_MISSING.md
- Verify any Ansible-compatibility claims against real
ansible-playbookoutput, not just documentation - Test your changes thoroughly (
crystal spec, andcompat/run.crfor plugin behavior changes) - Submit a pull request with a clear description
π License
MIT License - see LICENSE file for details.
π 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 it, line by line, 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 for Jinja2
templating, among other Crystal shards - see
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.
krikri - Ansible-compatible automation in Crystal π
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.921- Tagged
- Sep 14, 2026
- Commit
e5d3e7e38ead- Indexed
- not yet
Dependents
No indexed shard depends on this one yet.
Repository
github.com/weirdbricks/krikri
Metadata
- Created
- Aug 31, 2026
- Updated
- Sep 19, 2026
- Synced
- Sep 19, 2026
- Versions
- 29