Home
go-ansible documentation
A pure-Go, CGO_ENABLED=0, functional-parity port of Ansible.
go-ansible reimplements Ansible’s engine and modules as Go libraries instead of
wrapping the Python ansible-core binary. No Python interpreter, no C
extensions, no pip install — each component is an importable Go package that
compiles into your own static binary, and the wire formats it reads and writes
are byte-compatible with the real ansible-core tooling.
What exists today
All eight components are real, tested Go libraries with CI running on every push and pull request:
| Component | What it does |
|---|---|
vault | Reads and writes Ansible Vault 1.1 files — AES-256-CTR with a PBKDF2-HMAC-SHA256 key and an encrypt-then-MAC tag, byte-compatible with ansible-vault |
inventory | Parses Ansible-compatible INI and YAML inventories into the group/host graph, including group_vars/host_vars and host-pattern matching |
vars | Ansible’s variable precedence ladder — the fixed merge order from role defaults up through -e/--extra-vars |
template | Jinja2-compatible templating with Ansible’s filter and test library layered on top, including Ansible’s native-type rendering rule for a bare {{ expr }} |
facts | Fact gathering — the setup module equivalent — in one shell round trip, no Python required |
modules | The Ansible module execution protocol plus 576 modules: all of ansible.builtin and ansible.posix, and a curated 500 of community.general |
playbook | The playbook/role/task/handler engine tying all of the above together against a real play — loops, conditionals, blocks, become, roles, both execution strategies, retries, run_once, forks, vars_prompt, async/poll, dynamic inventory, ansible.cfg |
cli | 9 of real’s 10 ansible-* binaries — everything but ansible-test — each a thin wrapper over playbook/vault/inventory |
See the component overview for how these fit together, Roadmap for what’s still ahead beyond today’s module/collection surface, and the engine feature matrix on the landing page for exactly which playbook directives are implemented, re-checked against the code rather than assumed.
Why pure Go
Being pure Go buys three things Ansible’s own Python implementation cannot:
- A single static binary. No interpreter to install, no virtualenv, no
ansible[core]version pinned against a specific Python. Cross-compile once, ship one file. - CGO-free by construction. Every dependency here is pure Go — vault’s
crypto comes from
golang.org/x/crypto, not a C OpenSSL binding — so the usual cross-compilation and static-linking headaches don’t apply.clipublishes a multi-archFROM scratchOCI image on every version tag, something real Ansible’s own Python interpreter and pip dependencies can never reach. - Byte-for-byte compatibility, not a reinterpretation.
vaultreproduces the exact wire format ofansible.parsing.vault.VaultAES256; files written by one decrypt with the other. That’s the bar for every component here: not “does something similar,” but “reads what Ansible wrote, writes what Ansible reads” — verified against a real installedansible-core, not just internal review.
Security
A port that runs shell commands on remote targets has two defect classes to
answer for: a playbook value changing a command’s structure, and a credential
landing where ps can read it. Security states the control for
each, and what an audit of the whole stack found — most seriously, that a
managed host’s own data was evaluated as a template on the control node, so
one compromised target could run commands where the vault password and the
fleet’s SSH keys live. Alongside it: one command injection, one credential in
argv, a no_log secret printed under --diff, a vault password honoured from
an environment variable real has no equivalent of — and one that is
not about secrets at all, a playbook real would refuse outright running its first
four tasks for real before failing on the fifth. It also records the
ps-visibility boundary as measured rather than reasoned about, and the one
exposure that remains, named, with why it cannot be closed without cgo.
Repositories
| Repo | Role |
|---|---|
vault | Ansible Vault-compatible AES256 encryption for secrets |
inventory | Ansible-compatible inventory: INI/YAML parsers, groups, host/group vars, patterns |
vars | Ansible variable precedence engine |
template | Jinja2-compatible templating with Ansible’s filter and test library |
facts | Fact gathering, pure Go CGO=0 |
modules | Module execution protocol plus the 576-module core library |
playbook | Playbook/task/handler execution engine |
cli | 9 CLI binaries (all but ansible-test) |
brand | Logo, favicon and social banner |
docs | This documentation, published at go-ansible.github.io/docs |
The low-level SSH/local/become connection layer lives outside this org, in
the project-neutral
go-remoteexec/transport
(shared with go-puppet-bolt/bolt); modules, playbook, and cli depend
on it directly.