Skip to content

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:

ComponentWhat it does
vaultReads 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
inventoryParses Ansible-compatible INI and YAML inventories into the group/host graph, including group_vars/host_vars and host-pattern matching
varsAnsible’s variable precedence ladder — the fixed merge order from role defaults up through -e/--extra-vars
templateJinja2-compatible templating with Ansible’s filter and test library layered on top, including Ansible’s native-type rendering rule for a bare {{ expr }}
factsFact gathering — the setup module equivalent — in one shell round trip, no Python required
modulesThe Ansible module execution protocol plus 576 modules: all of ansible.builtin and ansible.posix, and a curated 500 of community.general
playbookThe 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
cli9 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. cli publishes a multi-arch FROM scratch OCI 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. vault reproduces the exact wire format of ansible.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 installed ansible-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

RepoRole
vaultAnsible Vault-compatible AES256 encryption for secrets
inventoryAnsible-compatible inventory: INI/YAML parsers, groups, host/group vars, patterns
varsAnsible variable precedence engine
templateJinja2-compatible templating with Ansible’s filter and test library
factsFact gathering, pure Go CGO=0
modulesModule execution protocol plus the 576-module core library
playbookPlaybook/task/handler execution engine
cli9 CLI binaries (all but ansible-test)
brandLogo, favicon and social banner
docsThis 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.

📖 go-ansible.github.io