Open-Source Wikis

/

Ansible

/

Lore

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 syntax

All 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.yml is 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 make import ansible_collections.<ns>.<col>... resolve installed collections through a MetaPathFinder.
  • lib/ansible/galaxy/collection/ was built out to fetch, install, and dependency-resolve collections via resolvelib.

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.py accreted 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 new TemplateEngine, replacing the old Templar over time.
  • lib/ansible/_internal/_yaml/ — instrumented YAML loaders that attach Origin to 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, and ssh.py all received multiple commits — bug-fixes and platform updates around remote management.
  • lib/ansible/modules/user.py overhaul. 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.py and task_executor.py saw refactoring activity.

Longest-standing features

  • The CLI dispatch shape. bin/ansiblelib/ansible/cli/adhoc.pyCLI.run() has the same skeleton it did in early 2.x. The CLI base class in lib/ansible/cli/__init__.py accreted features but kept its init_parser/post_process_args/run lifecycle.
  • 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__.py has 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 script inventory plugin) date from 2012.

Deprecated and removed features

  • Python 2 support. Removed in 2.12 (controller) and progressively from module_utils/basic.py (modules). The six compatibility shim still appears under lib/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 in lib/ansible/config/ansible_builtin_runtime.yml.
  • The Templar class is being phased out in favor of TemplateEngine. Both still exist; new code uses the latter.
  • include (alone) as a task keyword. Replaced by explicit include_tasks/import_tasks/include_role/import_role to 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:

  1. 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.
  2. The collection loader and namespace migration (v2.10, 2020-08-13). Already covered above. The most disruptive change post-2.0.
  3. 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 than lib/ 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.

Lore – Ansible wiki | Factory