Ansible Core Knowledge Patch
Use this skill when changing Ansible playbooks, inventories, controller plugins,
connection settings, test targets, or modules that depend on current
ansible-core behavior.
Working Method
- Determine the installed or pinned
ansible-coreversion from dependency manifests, execution-environment definitions, or lockfiles. - Inspect the affected playbooks and plugins for the migration points below.
- Open the topic reference before changing behavior that depends on exact configuration names, defaults, or plugin APIs.
- Apply only guidance introduced at or below the project's version. If the project is newer than the frontmatter version, treat this patch as potentially stale.
- Prefer project tests and observed runtime behavior when a project carries compatibility shims or backports.
Reference Index
| Reference | Topics |
| --- | --- |
| templating.md | Trust, single-pass evaluation, native values, strict conditionals, lazy templating, omit, sandboxing, and JSON profiles |
| plugins-and-extensions.md | Controller-side I/O, callback and strategy migrations, Jinja plugins, collection loading, markers, builtin names, and module_utils packages |
| connections-and-privilege.md | SSH agents and askpass, Paramiko removal, connection verbosity, local become, sudo_chdir, and Windows transports |
| playbooks-cli-and-inventory.md | CLI flags, inventory parsing, diagnostics, deprecated play syntax, argument-spec validation, and Galaxy behavior |
| modules-facts-and-windows.md | Fact access, file and package modules, result types, UTF-8 enforcement, Windows execution, and module patch behavior |
| testing-runtime-and-security.md | ansible-test environments and timeout diagnostics, supported runtimes, maintenance dates, and security fixes |
Highest-Priority Migration Checks
Treat templating as trusted and single-pass
- Jinja expressions in untrusted strings, including facts and module results, are not evaluated merely because the strings contain delimiters.
- Preserve trust when a plugin transforms a value that is intended to remain a template. Apply trust explicitly when a plugin creates such a value.
- Remove designs that depend on one template producing another template for a later pass.
- Do not wrap ordinary conditionals in
{{ ... }}. A whole trusted string expression is the narrow exception.
# Preferred
when: service_enabled | bool
# Avoid
when: "{{ service_enabled | bool }}"
Expect native values and boolean conditionals
- Template results retain native types; do not assume automatic string conversion.
- Do not assume
Nonebecomes an empty string. set_factpreserves the literal stringsyes,no,true, andfalsewhen they are supplied as strings.- A conditional must produce a boolean. Use an explicit comparison or a suitable conversion instead of relying on truthiness.
- Compatibility mode for broken conditionals is temporary and should only support a staged migration.
- name: Use an explicit boolean conversion
ansible.builtin.debug:
msg: enabled
when: feature_flag | bool
Audit lazy values and omit
- Only accessed portions of a structure are templated, so errors may surface later than structure construction.
omitis removed from its parent container during templating.- In loops, use
default(omit)on the value that should disappear from module arguments. - Code calling
Templar.template()must handleAnsibleValueOmittedErrorwhen the complete result is omitted.
- ansible.builtin.user:
name: "{{ item.name }}"
shell: "{{ item.shell | default(omit) }}"
loop: "{{ users }}"
Plugin and Extension Quick Reference
Controller-side code
- Task forks do not provide functional standard input, output, or error
streams. Use
Displayfor controller-side messages. - Convert Ansible-provided subclasses of Python builtins to plain native types before passing them to strict third-party libraries.
- Builtin Jinja filters and tests may be addressed with the
ansible.builtin.<name>form. - Python packages below
module_utilsmay contain__init__.py.
Callback, strategy, and Jinja migration
- Callback plugins must derive from
CallbackBase. - Replace the v1 callback API and
v2_on_anywith the specificv2_callbacks. - Third-party strategy plugins are deprecated without a planned replacement.
- Replace custom Jinja extensions with filter, test, or lookup plugins.
- A Jinja plugin must explicitly opt in before accepting an undefined top-level argument.
- Code using
environment.getitemmust handleMarkerErrorand return a marker, or explicitly opt in to marker values.
Connection and Privilege Quick Reference
SSH authentication
- The SSH connection uses
SSH_ASKPASSby default for password prompting. ansible,ansible-playbook, andansible-consolecan create or reuse an SSH agent.ansible_ssh_private_keyandansible_ssh_private_key_passphrasecan load a key from variables.- Set
SSH_AGENT_EXECUTABLEto choose the agent binary. - Use
ANSIBLE_SSH_VERBOSITYoransible_ssh_verbosityfor SSH-only verbosity.
Removed and deprecated transports
- Do not introduce a Paramiko dependency; migrate inventory and configuration to the SSH connection.
- Remove
DEFAULT_TRANSPORT=smart,PARAMIKO_HOST_KEY_AUTO_ADD, andPARAMIKO_LOOK_FOR_KEYS. - For the local connection, account for
become_strip_preambledefaulting to true andbecome_success_timeoutdefaulting to 10 seconds. sudo_chdirchanges directory before invokingsudo.
Playbook, CLI, and Inventory Quick Reference
- Use
--flush-cachewhere cache invalidation is needed withansible,ansible-console, oransible-pull. - Inventory files ending in
.iniare parsed by default unlessiniis put back intoINVENTORY_IGNORE_EXTS. - Use
DISPLAY_TRACEBACKto control tracebacks;-vvvis not the traceback switch. - Consume task-result
warningsanddeprecationswhen building diagnostic tooling. - Prefer
--inventoryover the deprecated--inventory-filealias. - Replace
play_hostswithansible_play_batch. - Remove empty
args, mapping-formaction, and combinations ofkey=valuearguments withargs. - Set
ansible_managedas a regular variable instead of usingDEFAULT_MANAGED_STR.
Validate play arguments
Set validate_argspec: true to select the required play name, or use a
string to select another entry from <playbook_name>.meta.yml.
# deploy.yml
- name: deploy
hosts: all
validate_argspec: true
# deploy.meta.yml
argument_specs:
deploy:
options:
environment:
type: str
required: true
Modules, Facts, and Results Quick Reference
- Migrate injected top-level facts such as
ansible_os_distributiontoansible_facts['os_distribution']. - Prefer the
varsandvarnameslookups over the internal variable cache. - Read per-volume-group logical volumes from each
ansible_facts['vgs']entry'slvssubkey when completeness matters. async_status.startedandasync_status.finishedare booleans, not integer flags.- Pass lists to
include_vars.extensionsandinclude_vars.ignore_files. - Use
encodingwithblockinfileandlineinfilefor non-UTF-8 files. - Expect
replaceto read, match, and write Unicode text. - Review automatic dependency installation in
apt,dnf5, anddeb822_repositorybefore relying on minimal target images. - Treat non-UTF-8 module response strings as errors; disabling strict checking is a compatibility escape hatch.
Test and Upgrade Checklist
- Exercise templates with facts and module-result strings containing literal Jinja delimiters.
- Test conditionals for genuine boolean results.
- Cover loop arguments that can resolve to
omit. - Run custom plugins without functional standard streams.
- Test SSH agent creation, key loading, and local become timeout behavior.
- Verify inventory discovery for
.inifiles. - Assert boolean async-status fields in integrations.
- Run Windows automation under the intended PowerShell host and application control policy.
- Give
ansible-testenough deadline headroom to emit pre-timeout thread diagnostics. - Check the detailed references before removing compatibility workarounds.