ansible-core 2.22 was released on 2 November 2026. Its headline feature is automatic secret masking: passwords, vault contents and other known secrets are now replaced with $REDACTED$ wherever Ansible prints or logs them. The release also adds Python 3.15 support, drops Python 3.12 on the control node, and removes several long-deprecated options.
Secret masking changes what you see in output and logs, so read the upgrade notes below before you roll 2.22 out to your automation servers or CI pipelines.
Ansible 2.22 at a Glance
| Release date | 2 November 2026 |
|---|---|
| Package | ansible-core 2.22.0 |
| Headline feature | Automatic secret masking ($REDACTED$) |
| Control node Python | Adds Python 3.15; drops Python 3.12 |
| Supported until | 31 May 2028 |
| Previous release | ansible-core 2.21 (supported until 30 November 2027) |
What’s New in Ansible 2.22
Automatic secret masking
Ansible now keeps a list of values it knows are secret and masks them in everything it writes: normal and verbose output, warnings, errors, module logs, and task results passed to callback plugins. Masking only affects what is displayed. Tasks, conditionals and registered variables still see the real values.
Values that are registered as secrets automatically include:
- Vault passwords and decrypted vault content, including vault-encrypted variable files
- Passwords entered with –ask-pass, –ask-become-pass and –ask-vault-pass
- Module options marked no_log
- Become passwords for sudo, su and runas
- SSH passwords, private keys and key passphrases, and WinRM/PSRP passwords
- vars_prompt answers with private: true (the default) and pause input typed without echo
- Output of the password and unvault lookups
You can register your own secrets with the new register_secret filter and mask strings with mask_secrets:
- name: Fetch an API token
ansible.builtin.set_fact:
api_token: "{{ lookup('ansible.builtin.env', 'API_TOKEN') | ansible.builtin.register_secret }}"
- name: This prints $REDACTED$ instead of the token
ansible.builtin.debug:
msg: "Token is {{ api_token }}"
Module and plugin authors get a new ansible.module_utils.secrets API with register_secret(), register_secrets() and mask_secrets(), and plugin options can be marked secret: true. PowerShell modules get the same through the Ansible.Secrets module utility.
Python support
The control node now supports Python 3.15 and no longer supports Python 3.12. Before upgrading, check the Python version that runs Ansible on your control node and CI runners:
ansible --version
Look at the python version line. If it shows 3.12, install a newer Python first.
Quieter connection output
The ssh, winrm and psrp connection plugins no longer print the raw stdout and stderr of commands at higher verbosity levels; they show only the return code. Python and PowerShell modules also stop adding the invocation key to results by default, which can be turned back on with the new INJECT_INVOCATION setting.
Other changes
- A new ansible_distribution_cpe_name fact, and “by-path” device links in hardware facts.
- ansible-config now works on all plugin types by default (-t all). Use -t base for the old behaviour.
- Removed: the ANSIBLE_CONNECTION_PATH and DEFAULT_LIBVIRT_LXC_NOSECLABEL settings, yes/no values for follow_redirects in url/uri, and old deprecated yum_repository parameters.
- Deprecated: ansible.module_utils.six now warns at runtime and will be removed in 2.24. Treating a non-zero rc without a failed key as a failure now warns, and that special handling goes away in 2.24.
Before You Upgrade: Behaviour Changes
Most playbooks run unchanged, but check these points:
- debug output: printing a secret with the debug module now shows $REDACTED$ at every verbosity level, and there is no per-task switch to turn it off. To inspect a value while troubleshooting, write it to a protected file instead.
- no_log placeholders: the old VALUE_SPECIFIED_IN_NO_LOG_PARAMETER, NOT_LOGGING_PARAMETER and ******** placeholders are replaced by $REDACTED$. Tests or tooling that look for the old strings need updating.
- Short secrets: there is no minimum length, so a short password can also mask matching text inside unrelated words in your output.
- Custom callback plugins: task results arrive already masked, but anything a callback writes on its own (task names, stats, files) should go through mask_secrets().
- Network devices: masking does not cover the persistent_log_messages log, because persistent connections run in a separate process. Passwords can appear there in plain text, so enable that option only while debugging.
- ANSIBLE_DEBUG=1: raw command output can appear before secrets are registered, so treat debug logs as sensitive.
The full list is in the official ansible-core 2.22 porting guide and changelog.
Support Timeline
ansible-core 2.22 is supported until 31 May 2028. ansible-core 2.21 remains supported until 30 November 2027, so you have time to test secret masking before upgrading production. See the full lifecycle on the Ansible 2.22 release page and every version on the Ansible release history.
How to Upgrade to Ansible 2.22
ansible-core is distributed through PyPI. If you installed it with pipx, upgrade it with:
pipx upgrade ansible-core
If you installed it with pip in a virtual environment, activate the environment and run:
python3 -m pip install --upgrade "ansible-core==2.22.*"
Then confirm the version:
ansible --version
If you use the full community ansible package (ansible-core plus collections) rather than ansible-core alone, note that the community release built on ansible-core 2.22 (Ansible 15) was still in development when this article was written. Upgrade the ansible package once that release is available.
New to Ansible? Start with our Ansible beginner’s guide, how Ansible works and the key Ansible commands.
Should You Upgrade?
Yes, for most teams. Secret masking closes a common source of leaked credentials in CI logs and shared terminals. Test it in a staging pipeline first: run your main playbooks with -v, check that nothing you rely on in the output is now masked, and update any tests that look for the old no_log placeholders. Network automation users should also review where persistent connection logs are written.
How did it make you feel?
