ansible/ansible
Lore
The history of the ansible-core codebase, derived from git history, tag dates, and the on-disk shape of the tree. Every era and milestone below is anchored to a date.
Genesis (Feb 2012)
The first commit is dated 2012-02-23:
2012-02-23T14:17:24-05:00 Genesis.
2012-02-23T14:18:51-05:00 Initial library directory
2012-02-23T14:19:28-05:00 Add SSH-agent usage instructions
2012-02-23T14:20:28-05:00 Example for list of hosts syntaxAll four early commits are by Michael DeHaan, who is credited in the README as the project's creator. The opening week's work brought in the SSH transport, an inventory file, and a single-binary CLI design — the bones still recognizable in today's lib/ansible/cli/__init__.py.
The 2.x era opens (Mar 2018 – Oct 2019)
The git tag history readable in this repository starts at v2.5.0 (2018-03-22) and sees five minor releases in fast succession:
| Tag | Date | Theme |
|---|---|---|
| v2.5.0 | 2018-03-22 | Major plugin refactors, vault id support, --vault-id flag |
| v2.6.0 | 2018-06-28 | Pipelining/become unification, network module overhaul |
| v2.7.0 | 2018-10-03 | More network platforms, becoming agnostic of the becoming user's shell |
| v2.8.0 | 2019-05-16 | Module documentation overhaul, big collection-loader groundwork |
| v2.9.0 | 2019-10-31 | The last release before The Big Split |
This era was the last in which Ansible shipped as a single monolith with hundreds of cloud, network, OS, and SaaS modules in one tarball.
The Great Collection Split (Aug 2020)
v2.10.0 (2020-08-13) marked the largest restructuring in the project's history. Ansible the package was decomposed into:
- ansible-core (the engine, the CLIs, ~73 essential modules) — this repository.
- ansible (the meta-package) — a curated set of collections layered on top of ansible-core.
- community.general, community.network, ansible.posix, cloud.aws, and dozens of vendor-namespaced collections.
The artifacts of this split are visible across the tree:
lib/ansible/config/ansible_builtin_runtime.ymlis a giant redirect table mapping every legacy module/plugin name to its new fully-qualified collection name.lib/ansible/utils/collection_loader/was added to makeimport ansible_collections.<ns>.<col>...resolve installed collections through aMetaPathFinder.lib/ansible/galaxy/collection/was built out to fetch, install, and dependency-resolve collections viaresolvelib.
Many community.* modules' git history pre-dates the split because they were extracted intact from this repository.
Steady cadence (2021–2023)
After the split, releases settled into a roughly twice-a-year cadence:
| Tag | Date |
|---|---|
| v2.11.0 | 2021-04-26 |
| v2.12.0 | 2021-11-08 |
| v2.13.0 | 2022-05-16 |
| v2.14.0 | 2022-11-07 |
| v2.15.0 | 2023-05-15 |
| v2.16.0 | 2023-11-06 |
| v2.17.0 | 2024-05-20 |
Two themes dominate this period:
- Python-version churn. The minimum controller Python steadily climbed: 2.7 → 3.5 → 3.8 → 3.9 → 3.10 → 3.11 → 3.12 (current). Each bump removed compatibility cruft. The current floor is enforced in
lib/ansible/cli/__init__.py:_PY_MIN = (3, 12). - Plugin loader hardening.
lib/ansible/plugins/loader.pyaccreted layers for FQCN resolution, deprecation warnings, redirect handling, and circular-redirect protection.
The trust and templating rewrite (2024–2025)
v2.18.0 (2024-11-04) and v2.19.0 (2025-07-21) delivered a deep restructure of how variables flow through the engine.
Before, every YAML scalar was a plain Python str. Templating was done by string-matching {{ ... }} and rendering with Jinja. The downside: a fact gathered from a remote host might contain {{ ... }} that would inadvertently re-template, becoming a vector for template injection.
After the rewrite, scalars carry tags via AnsibleTagHelper and AnsibleTaggedObject:
Origin— where this value came from (filename + line + column).TrustedAsTemplate— whether this string is allowed to participate in templating.VaultedValue— encrypted at rest, decrypted on read.
You can see the bulk of this work under lib/ansible/_internal/:
lib/ansible/_internal/_datatag/— tag definitions.lib/ansible/_internal/_templating/— the newTemplateEngine, replacing the oldTemplarover time.lib/ansible/_internal/_yaml/— instrumented YAML loaders that attachOriginto every scalar.
The legacy lib/ansible/template/__init__.py:Templar is still present (and large), but most internal call sites moved to the new TemplateEngine. This is the most invasive controller change in the post-2.10 era.
Internalization wave (2024–2026)
Around the same time, the project moved a lot of previously-public surface area into the leading-underscore _internal namespace, signaling "do not import from outside ansible-core":
lib/ansible/_internal/_task.py(1,444 lines) — the over-the-wire task representation that crosses the controller/worker boundary.lib/ansible/_internal/_worker/— worker-side RPC plumbing.lib/ansible/_internal/_plugins/_strategy.py— strategy plugin shared base helpers.lib/ansible/_internal/_powershell/— PowerShell glue extracted from the executor.
Sanity-test rules were updated to enforce that nothing outside ansible-core imports from _internal.
Recent and ongoing (2025–2026)
The 2.20 line tagged on 2025-11-04, and devel is now identified as 2.22.0.dev0 in lib/ansible/release.py. Focus areas visible in the last 90 days of commits:
- Connection layer maintenance.
lib/ansible/plugins/connection/psrp.py,winrm.py, andssh.pyall received multiple commits — bug-fixes and platform updates around remote management. lib/ansible/modules/user.pyoverhaul. Seven commits in 90 days on this single 3,564-line file. It's the largest module in the tree and a long-standing source of POSIX-platform-specific complexity.- Configuration changes. Eight commits to
lib/ansible/config/base.yml, the registry of every Ansible config option. - AnsiBallZ improvements. Both
module_common.pyandtask_executor.pysaw refactoring activity.
Longest-standing features
- The CLI dispatch shape.
bin/ansible→lib/ansible/cli/adhoc.py→CLI.run()has the same skeleton it did in early 2.x. TheCLIbase class inlib/ansible/cli/__init__.pyaccreted features but kept itsinit_parser/post_process_args/runlifecycle. - The plugin types. All 17 plugin types (
action,become,cache,callback, ...) predate the v2.10 split. Adding a new plugin type is rare and requires a deep-architecture change. - Vault.
lib/ansible/parsing/vault/__init__.pyhas been around since 2014 (per the file header) and still uses the same AES-256-CTR scheme. The format is versioned ($ANSIBLE_VAULT;1.1;...and;1.2;with a vault label). - YAML inventory. The simple INI/YAML inventory plugin pair has been present since the beginning. Dynamic inventory scripts (now wrapped by the
scriptinventory plugin) date from 2012.
Deprecated and removed features
- Python 2 support. Removed in 2.12 (controller) and progressively from
module_utils/basic.py(modules). Thesixcompatibility shim still appears underlib/ansible/module_utils/six/because module code targets a wider Python range. - Bundled modules. Hundreds of cloud, network, OS, and SaaS modules were removed from
lib/ansible/modules/between v2.9 and v2.10 and republished in collections. The redirects live inlib/ansible/config/ansible_builtin_runtime.yml. - The
Templarclass is being phased out in favor ofTemplateEngine. Both still exist; new code uses the latter. include(alone) as a task keyword. Replaced by explicitinclude_tasks/import_tasks/include_role/import_roleto disambiguate dynamic vs. static behavior.- Old vault format 1.0 without vault id. Still readable; new files use 1.1 or 1.2.
Major rewrites
The post-2.0 codebase has weathered three notable structural rewrites:
- Strategy plugins (~v2.0). Task scheduling was extracted out of the runner into pluggable strategies (
linear,free). Predates the public history visible in this repo. - The collection loader and namespace migration (v2.10, 2020-08-13). Already covered above. The most disruptive change post-2.0.
- Trust/datatag templating (v2.18–2.19, late 2024 – mid 2025). Replaced ad-hoc string templating with a formal trust model.
Growth trajectory
- Authors over time. ~6,433 unique authors recorded in
git log. The README cites "over 5,000 users" — the number has continued to climb. Recent activity (last 90 days: 119 commits) is more concentrated among core maintainers than the pre-split era, consistent with an engine that pushes most new content into collections. - Codebase size. Pre-split, ansible-core was a single tarball with thousands of modules. Post-split it stabilized around the current footprint: 583 source files in
lib/, ~136,000 Python lines, and a much larger test surface thanlib/itself (1,213 test files).
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.