Ansible 15 Porting Guide

Ansible 15 is based on Ansible-core 2.22.

We suggest you read this page along with the Ansible 15 Changelog to understand what updates you may need to make.

Introduction

This release adds secret masking. Ansible now registers known secret values, such as decrypted vault content, no_log module options, and prompted passwords, and replaces them with $REDACTED$ wherever it writes output. The values themselves are unchanged, so playbooks keep working with the real data and only the rendered output is masked.

Most playbooks need no changes. Content that inspected the VALUE_SPECIFIED_IN_NO_LOG_PARAMETER placeholder, and modules or plugins that stripped secrets from results by hand, should be reviewed. Authors of custom callback plugins should update them to declare support for masking, as described in Callback plugins.

We recommend you test your playbooks, callback plugins, and any tooling that consumes Ansible output in a staging environment with this release. See Masking secrets in Ansible output for the user guide and Handling secrets in modules and plugins for the developer guide.

Playbook

Secret masking

Ansible now masks registered secrets in its output. Values such as decrypted vault content, no_log module option values, and prompted passwords are replaced with $REDACTED$ on the screen, in the log_path log file, in callback output, and in module logs on the managed node. The values themselves are unchanged and remain usable by tasks. Use the new register_secret filter to register your own values and the mask_secrets filter to redact registered secrets from a string. See Masking secrets in Ansible output for details, including how secrets are matched and the limitations of masking.

Module options marked with no_log: true are no longer replaced with the literal VALUE_SPECIFIED_IN_NO_LOG_PARAMETER in the module result. The real value is kept in the result and registered as a secret so it is masked in output. Playbooks that compared a result value against VALUE_SPECIFIED_IN_NO_LOG_PARAMETER should be updated.

One consequence of this change is that a no_log option value is now masked wherever it appears in later output, not only in the module result. A very short value, such as one or two characters, is also masked inside unrelated words and values, which can make output hard to read, and the pattern of placeholders can reveal the value. See Short secrets for details.

The register_secret filter fails on a value that is not a string or is empty after leading and trailing whitespace is stripped, because such a value cannot be masked. Set the filter’s validation_action option to warn or ignore to return the value unregistered instead of failing.

Using the debug module with msg or var to show a password or other sensitive value on the screen no longer works. The debug module writes through Display, so a registered secret is shown as $REDACTED$ wherever it appears, including inside a larger variable and at any verbosity level. There is no option to disable masking for a single task.

If you need to see the real value, for example to confirm that a vault variable decrypts to what you expect, write it to a file instead of displaying it. A file written by a module is not an output boundary, so the file contains the unmasked value:

- name: Write the secret to a file for inspection
  ansible.builtin.copy:
    content: "{{ db_password }}"
    dest: /tmp/db_password.txt
    mode: "0600"
  delegate_to: localhost

Read the file outside of Ansible and delete it when you are done.

Engine

Secret masking

Masking is applied at the points where data leaves Ansible rather than to the data itself:

  • All Display output, including the screen, the log_path log file, warnings, deprecation messages, errors, and tracebacks.

  • The result mapping of every task result passed to a callback plugin.

  • Module logging to syslog and the Windows Event Log, including the module invocation entry.

Secrets registered in a worker process or inside a module on a managed node are sent back to the controller and registered there, so a value discovered by one task is masked in every later task. Registered secrets that appear in a module’s arguments are passed to the module so module-side logging can mask them.

There is no minimum or maximum secret length. A registered secret is masked wherever it appears, including inside a longer word or value. Overlapping and adjacent secrets are replaced with a single placeholder. See How registered secrets are matched for the details. Leading and trailing whitespace is stripped from a value before it is registered, so a secret read from a file with a trailing newline is masked with or without that newline. Masking only matches the exact registered string, so an encoded or hashed copy of a secret is not masked unless it is registered as well. The JSON-escaped form of a secret is the one exception and is always masked. Masking also only covers messages Ansible writes through Display. Messages that other Python libraries emit with the standard logging module share the log_path file and are not masked.

Plugin API

Secret masking API

  • The ansible.module_utils.secrets module is a new public API providing register_secret(), register_secrets(), and mask_secrets(). See Handling secrets in modules and plugins.

  • The Ansible.Secrets C# module util provides the same API for PowerShell modules through [Ansible.Secrets.SecretMasker].

  • Plugin configuration options can set secret: true to register the resolved value as a secret regardless of the source that set it.

  • AnsibleModule no longer strips no_log values from module results.

Values registered through the secrets API are masked in Display output, callback output, and module logs. Any plugin or module that discovers a sensitive value at runtime, such as a token returned by an API, should register it as soon as it is known.

The secret configuration keyword is only supported for the str, string, and list types and is not supported on suboptions. Declaring it on any other type is an error when the plugin configuration is loaded. The ansible-core connection and become plugins use it for their password and key options, and plugins that accept a password or token should do the same.

Modules that relied on remove_values() or sanitize_keys() to strip no_log values from their results should remove those calls. The values are now masked at the output boundary instead, and both helpers are deprecated.

Callback plugins

The result mapping of every task result passed to a callback plugin is now masked before the callback receives it. Every string value and every string dictionary key in result.result is masked at any depth of nesting, including inside loop results. Existing callbacks keep working without changes and no longer see the real value of any registered secret in the result. Masking also changes some values that are not strings:

  • An int or float whose text form is a registered secret is replaced with the placeholder string. A callback that expects a number in a result must handle receiving the string $REDACTED$ instead when that number was registered as a secret.

  • When two dictionary keys mask to the same placeholder, the second is renamed with a numeric suffix such as $REDACTED$ (2) so that no entry is lost.

  • stdout_lines and stderr_lines are rebuilt from the masked stdout and stderr so that a secret spanning several lines is masked in the lines as well.

Only result.result is masked. Task and play names, the warnings, deprecations, and exception attributes of the result, the statistics passed to v2_playbook_on_stats(), and anything a callback derives itself are masked only when written through Display(). A callback that writes such data to a file, socket, HTTP request, database, or any other destination must pass it through ansible.module_utils.secrets.mask_secrets() first.

To update a custom callback plugin:

  1. Audit every place the callback writes data other than through Display(), and mask any data that does not come from result.result with mask_secrets().

  2. Remove any custom code that stripped no_log values or checked for VALUE_SPECIFIED_IN_NO_LOG_PARAMETER, as results no longer contain that placeholder.

  3. Check any code that relies on the type of a result value, since a number registered as a secret is replaced with a string.

The following example supports both ansible-core 2.22 and earlier versions. On versions before 2.22 the ansible.module_utils.secrets import fails and the result already has no_log values removed, so mask_secrets() falls back to returning the text unchanged. On 2.22 and later the result is already masked and mask_secrets() covers the task name written alongside it:

import json

from ansible.plugins.callback import CallbackBase

try:
    from ansible.module_utils.secrets import mask_secrets
except ImportError:
    # ansible-core < 2.22 has no secret masking API. Results on those versions
    # already have no_log values removed, so there is nothing to mask here.
    def mask_secrets(value):
        return value


class CallbackModule(CallbackBase):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'notification'
    CALLBACK_NAME = 'namespace.collection_name.json_file'
    CALLBACK_NEEDS_ENABLED = True

    def v2_runner_on_ok(self, result):
        # result.result is already masked on 2.22+, but the task name is not, so mask
        # the serialized form before writing it.
        entry = {'task': result.task_name, 'result': result.result}
        entry_json = mask_secrets(json.dumps(entry, default=str))

        with open('/var/log/ansible-results.jsonl', 'a') as fd:
            fd.write(entry_json + '\n')

The junit and tree callbacks shipped with ansible-core are examples of callbacks that write to files and mask everything they write. The task no_log keyword continues to censor the entire result regardless of masking as it affects the result value provided. See Callback plugins for more details.

Command Line

  • Passwords entered for --ask-pass, --ask-become-pass, and --ask-vault-pass are registered as secrets and masked in output.

  • Values entered for a vars_prompt with private: true (the default) are registered as secrets and masked in output.

Deprecated

  • ansible.module_utils.basic.heuristic_log_sanitize() is deprecated and will be removed in ansible-core 2.25. Secret values are now masked automatically. Use the ansible.module_utils.secrets API to handle secrets manually.

  • ansible.module_utils.common.parameters.remove_values() and sanitize_keys() are deprecated and will be removed in ansible-core 2.25. Secret values are now masked automatically. Use the ansible.module_utils.secrets API to handle secrets manually.

  • The live argument of ansible.utils.cmd_functions.run_cmd() is deprecated and will be removed in ansible-core 2.25 because it bypasses secret masking. Callers that need to stream output live should run the subprocess themselves and mask any secrets in the output.

Failure inference from non-zero rc

Failure inference for modules and actions that return a non-zero rc value and no failed value is deprecated and emits a runtime deprecation warning. Modules and actions may use any logic desired to determine failure (including consulting rc), but failures must be explicitly communicated in the task result by setting failed true, or via methods that do so implicitly, such as fail_json or raising an unhandled error. When failure inference is removed in 2.24, the rc key will receive no special attention during task result processing.

Modules

Modules removed

The following modules no longer exist:

  • No notable changes

Deprecation notices

No notable changes

Noteworthy module changes

  • Module options marked no_log: true keep their real value in the module result instead of being replaced with VALUE_SPECIFIED_IN_NO_LOG_PARAMETER. The value is registered as a secret and masked in output. See How masking changes no_log.

  • Values logged by AnsibleModule.log() and the module invocation log entry now use $REDACTED$ in place of the previous NOT_LOGGING_PARAMETER and NOT_LOGGING_PASSWORD placeholders, and any other registered secret in the message is masked.

  • AnsibleModule.log() and the module invocation log no longer apply the heuristic_log_sanitize() heuristics. For example, user:password@host in a URL is no longer rewritten unless the password is a registered secret.

  • AnsibleModule.run_command() no longer replaces password-like arguments such as --password=... with ******** in the cmd value of a failure result, and no longer passes the msg value through heuristic_log_sanitize().

  • The uri module no longer rewrites response keys to strip no_log values. Registered secrets are masked in output instead.

Only registered secrets are masked in the values above. Modules that pass a secret on the command line or embed one in a URL, where that secret is not a no_log option, should register it with ansible.module_utils.secrets.register_secret().

Plugins

Noteworthy plugin changes

  • The following plugin options are marked secret: true and are masked in output:

    • ssh connection plugin: password, private_key, and private_key_passphrase

    • winrm connection plugin: password

    • psrp connection plugin: password and certificate_key_password

    • sudo, su, and runas become plugins: become_pass

    • url lookup plugin: password

  • The password lookup registers the generated plaintext password as a secret. The unvault lookup registers the entire decrypted content of each file as a single secret. The vault and unvault filters register the vault password passed to them, and also register the plaintext being encrypted or decrypted as a single secret.

  • Vault-encrypted files loaded as variables are parsed and each value is registered individually, so values inside them are masked wherever they appear on their own.

  • The pause action registers user input as a secret when echo: false is set.

  • Connection plugin authors should audit any code that displays the raw standard output or standard error of a module invocation. Secrets that a module registers during its run are returned in the raw JSON result and are not masked until the controller processes it. The connection plugins shipped with ansible-core only display raw module output when ANSIBLE_DEBUG is enabled.

  • Callback plugins receive task results with registered secrets already masked. The junit and tree callbacks pass everything they write to a file through mask_secrets() so that task and play names and other data not taken from the result are masked as well. See Callback plugins.

Porting custom scripts

No notable changes

Networking

Secret masking does not apply to the messages logged by the persistent_log_messages option. Persistent connections run in a separate ansible-connection process that does not receive the secrets registered by the controller, so passwords and other sensitive configuration sent over the connection are written to the log in plain text. Only enable this option while debugging and treat the resulting log as sensitive.

Porting Guide for v15.0.0a4

Added Collections

  • everpure.flasharray (version 1.45.1)

  • everpure.flashblade (version 1.28.0)

Breaking Changes

ansible.windows

  • dsc3 - Check mode now runs dsc config set --what-if instead of dsc config test so the reported changes align with what dsc would do. Group resources such as Microsoft.DSC/Group and Microsoft.DSC/Include do not support what-if and fail in check mode.

Deprecated Features

  • The collection purestorage.flasharray was renamed to everpure.flasharray. For now both collections are included in Ansible. The content in purestorage.flasharray has been replaced by deprecated redirects in Ansible 15.0.0. The collection will be completely removed from Ansible 17. Please update your FQCNs from purestorage.flasharray to everpure.flasharray (https://forum.ansible.com/t/46435).

  • The collection purestorage.flashblade was renamed to everpure.flashblade. For now both collections are included in Ansible. The content in purestorage.flashblade has been replaced by deprecated redirects in Ansible 15.0.0. The collection will be completely removed from Ansible 17. Please update your FQCNs from purestorage.flashblade to everpure.flashblade (https://forum.ansible.com/t/46435).

Ansible-core

  • task result - Inferred task failure from a non-zero rc key and absence of a failed key emits a runtime deprecation warning. Actions and modules must explicitly communicate failure by setting the failed key, using APIs that do so, or raising an unhandled exception. In ansible-core 2.24, the rc key will receive no special handling during task result processing.

Porting Guide for v15.0.0a3

Breaking Changes

amazon.aws

cisco.iosxr

  • The gRPC connection plugin requires protobuf>=3.20.0 and grpcio>=1.48.4 on the Ansible controller. Update the controller environment before using this connection plugin. Other connection plugins are unaffected.

community.aws

theforeman.foreman

  • activation_keys role - The defaults for lifecycle_environment and content_view were removed and the variables are now optional. This allows using content_view_environments to assign Content View Environments instead.

  • convert2rhel role - The foreman_convert2rhel_content_view variable was replaced by foreman_convert2rhel_content_view_environments to support Katello 5.0 which removed the old CV API. This breaks compatibility with Katello older than 4.15.

Deprecated Features

amazon.aws

community.aws

  • inspector_target - The module has been deprecated as Amazon has retired the Amazon Inspector Classic service on May 20, 2026 (Complete End of Life), revoking access to its console, APIs, and associated resources. The module will be removed in version 12.0.0 (https://github.com/ansible-collections/community.aws/pull/2485).

community.dns

community.proxmox

  • proxmox_cluster_firewall - add deprecation notice for proxmox_cluster_firewall module. This module will be renamed to proxmox_cluster_firewall_options in 3.0.0.

  • proxmox_cluster_firewall_security_group - the default of purge_omitted_rule_fields will change from false to true in community.proxmox 3.0.0. With true, optional rule fields that are omitted from a rules entry are removed from the existing rule. Set purge_omitted_rule_fields=false to keep preserving omitted rule fields in 3.0.0 (https://github.com/ansible-collections/community.proxmox/issues/278, https://github.com/ansible-collections/community.proxmox/pull/527).

  • proxmox_node_firewall - add deprecation notice for proxmox_node_firewall module. This module will be renamed to proxmox_node_firewall_options in 3.0.0.

  • proxmox_node_firewall_info - add deprecation notice for proxmox_node_firewall_info module. This module will be renamed to proxmox_node_firewall_options_info in 3.0.0.

Porting Guide for v15.0.0a2

Breaking Changes

community.vmware

  • Removed support for ansible-core < 2.21.0.

vmware.vmware_rest

  • appliance_monitoring_query - The interval, function, start_time and end_time parameters have been grouped under a new required item dictionary parameter to match the vSphere 9.1.0 API specification. The module will not work with older versions of the API.

  • appliance_networking_interfaces_ipv4 - The state parameter now accepts present instead of set. Playbooks that explicitly set state: set must be updated to state: present.

  • appliance_networking_interfaces_ipv6 - The state parameter now accepts present instead of set. Playbooks that explicitly set state: set must be updated to state: present.

  • appliance_system_storage - The state parameter now accepts resize-ex instead of resize_ex. This was done to better align with the API expectations.

  • vcenter_folder_info - The type parameter (and its filter_type alias) has been moved into a new filter dictionary as filter.type, reflecting the Vcenter.Folder.FilterSpec object introduced in the vSphere 9.1.0 API specification. Playbooks that set type or filter_type at the top level must now use filter.type. The folders, names, parent_folders, and datacenters filters remain top-level parameters.

  • vcenter_folder_info and vcenter_network_info - The ‘value’ return is not guaranteed to be a list. If a list is desired, the ‘info’ return will always be a list (as documented)

  • vcenter_host_info - The standalone parameter has been moved into a new filter dictionary as filter.standalone, reflecting the Vcenter.Host.FilterSpec object introduced in the vSphere 9.1.0 API specification. Playbooks that set standalone at the top level must now use filter.standalone. The other host filters remain top-level parameters.

  • vcenter_ovf_libraryitem - The deployment_spec.accept_all_EULA parameter has been renamed to deployment_spec.accept_all_eula (snake_case) in the vSphere 9.1.0 API specification and module arguments. The module will not work with older versions of the API.

  • vcenter_vm_guest_filesystem_directories - The ‘present’, ‘absent’, ‘create_temporary’ states have been removed and replaced with options that better reflect the action taken by the API.

  • vcenter_vm_guest_filesystem_directories - The state option has no default value and must be specified.

Major Changes

Ansible-core

  • callback plugins - task results passed to callback plugins now always have any registered secrets replaced with $REDACTED$, so callbacks no longer need to mask the result themselves. The ANSIBLE_SUPPORTS_MASKING callback class attribute introduced in ansible-core 2.22.0b1 to opt into receiving unmasked results has been removed and is now ignored.

dellemc.openmanage

  • Added BIOS registry info module: idrac_bios_registry_info.

  • Added network attributes info modules: idrac_network_attributes_info, and idrac_network_info.

  • Added session info module: idrac_session_info.

  • Complete removal of OMSDK library dependency from the collection.

  • Enhanced idrac_certificates module with SCEP_CA_CERT support for ACME and SCEP enrollment.

  • Enhanced idrac_lifecycle_controller_logs module with pagination, filtering, and export capabilities.

  • Enhanced idrac_session module with self-session protection to prevent accidental lockout when deleting sessions.

  • Removed 8 deprecated OMSDK-dependent modules: dellemc_configure_idrac_eventing, dellemc_configure_idrac_services, dellemc_idrac_lc_attributes, dellemc_system_lockdown_mode, idrac_network, idrac_timezone_ntp, dellemc_idrac_storage_volume, and idrac_syslog.

  • Removed OMSDK requirement from idrac_system_info module.

  • Removed OMSDK-specific code from dellemc_idrac.py utility module.

  • Removed deprecated parameters from idrac_bios module (share_name, share_user, share_password, share_mnt, boot_sources).

netapp.ontap

  • na_ontap_active_directory - AWS Lambda support added to the module.

  • na_ontap_active_directory_domain_controllers - AWS Lambda support added to the module.

  • na_ontap_dns - GCNV support added to the module.

  • na_ontap_ems_filter - GCNV support added to the module.

  • na_ontap_export_policy - GCNV support added to the module.

  • na_ontap_export_policy_rule - GCNV support added to the module.

  • na_ontap_ldap_client - GCNV support added to the module.

  • na_ontap_license - GCNV support added to the module.

  • na_ontap_nvme - AWS Lambda support added to the module.

  • na_ontap_nvme_subsystem - AWS Lambda support added to the module.

  • na_ontap_qtree - GCNV support added to the module.

  • na_ontap_quotas - GCNV support added to the module.

  • na_ontap_rest_cli - GCNV support added to the module.

  • na_ontap_rest_info - GCNV support added to the module.

  • na_ontap_restit - GCNV support added to the module.

  • na_ontap_security_certificates - AWS Lambda support added to the module.

  • na_ontap_security_ipsec_config - AWS Lambda support added to the module.

  • na_ontap_security_ipsec_policy - AWS Lambda support added to the module.

  • na_ontap_snapshot - GCNV support added to the module.

  • na_ontap_snapshot_policy - GCNV support added to the module.

  • na_ontap_volume - GCNV support added to the module.

vmware.vmware_rest

  • vcenter_vm_guest_filesystem_directories - The module now raises an error when the vSphere API request fails (for example when creating a directory that already exists) instead of silently returning a successful, unchanged result. Playbooks that relied on the previous behavior should handle the failure explicitly.

Removed Features

community.vmware

dellemc.openmanage

  • dellemc_configure_idrac_eventing - Use idrac_attributes as alternative.

  • dellemc_configure_idrac_services - Use idrac_attributes as alternative.

  • dellemc_idrac_lc_attributes - Use idrac_attributes as alternative.

  • dellemc_idrac_storage_volume - Use idrac_storage_volume as alternative.

  • dellemc_system_lockdown_mode - Use idrac_attributes as alternative.

  • idrac_network - Use idrac_network_attributes as alternative.

  • idrac_syslog - Use idrac_attributes as alternative.

  • idrac_timezone_ntp - Use idrac_attributes as alternative.

vmware.vmware_rest

Deprecated Features

  • The cisco.ucs collection will be removed from Ansible 16. There is no active development happening on the collection. This has moved to cisco.intersight which is also part of the ACP. See the removal discussion for details. After removal, users can still install this collection with ansible-galaxy collection install cisco.ucs.

community.vmware

vmware.vmware_rest

  • Deprecate appliance_health_applmgmt_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_health_databasestorage_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_health_load_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_health_mem_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_health_storage_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_health_swap_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_health_system_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_networking_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_networking_interfaces_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_networking_interfaces_ipv4_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_networking_interfaces_ipv6_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_system_time_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_system_version_info module. Use vmware.vmware.appliance_info

  • Deprecate appliance_vmon_service and appliance_vmon_service_info modules as the endpoint has been removed. Use appliance_services and appliance_services_info instead.

  • Deprecate vcenter_folder_info module. Use vmware.vmware.folder_info

  • Deprecate vcenter_host_info module. Use vmware.vmware.esxi_info

  • Deprecate vcenter_vm_guest_filesystem_directories module. Use ansible.builtin.file

  • Deprecate vcenter_vm_hardware_floppy and vcenter_vm_hardware_floppy_info modules as floppy drives are legacy hardware.

  • Deprecate vcenter_vm_info module. Use vmware.vmware.vm_info

  • Deprecate vcenter_vm_power_info module. Use vmware.vmware.vm_info

  • Deprecate vcenter_vmtemplate_libraryitems module. Use vmware.vmware.deploy_content_library_template or vmware.vmware.content_template

Porting Guide for v15.0.0a1

Added Collections

  • ansible.mariadb (version 6.0.2)

Known Issues

Ansible-core

  • Secret masking - when ANSIBLE_DEBUG=1 is set, the raw stdout and stderr of commands executed on the target, including module results, are displayed before the secrets contained in the module result have been registered for masking. Secrets which are only known to the module, such as no_log option values, may therefore be shown in plaintext in debug output.

Breaking Changes

Ansible-core

  • AnsibleModule - log() and the automatic invocation logging now only redact values registered as secrets (such as no_log option values) and no longer apply the heuristic_log_sanitize() heuristics, for example user:password@host in URLs is no longer rewritten unless the password is a registered secret. no_log and password-like options are logged as $REDACTED$ instead of NOT_LOGGING_PARAMETER or NOT_LOGGING_PASSWORD.

  • AnsibleModule - run_command() no longer rewrites the cmd value in a failure result to replace password-like arguments (such as --password=...) with ********, and the msg value is no longer passed through heuristic_log_sanitize(). Registered secrets in these values are still redacted in output. Modules that pass a secret on the command line which is not a no_log option should register it with ansible.module_utils.secrets.register_secret().

  • Module options that are marked as no_log: true will no longer be redacted literally as "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" in the module result and invocation.module_args. Instead, the actual value is registered as a secret and is only redacted in generated output, allowing these values to be used by subsequent tasks without any loss of data. The value is still redacted in callback output and module logging. Playbooks or tests that check for the VALUE_SPECIFIED_IN_NO_LOG_PARAMETER placeholder in results should be updated.

  • ansible-config - all actions now default to -t all, so configuration files using sections owned by plugins (for example, [ssh_connection]) are no longer reported as unknown sections, and keys within those sections are actually validated. Use -t base to retain the previous behavior (https://github.com/ansible/ansible/issues/86398).

  • uri - response keys are no longer rewritten to strip no_log values (previously done with sanitize_keys()); registered secrets are masked in output instead.

cisco.nxos

  • nxos_l2_interfaces - Port-channel member interfaces are now excluded from gathered, parsed, and overridden/deleted states. Attempting to configure L2 settings directly on a port-channel member via merged, replaced, or deleted (with explicit config) states will now raise an error. Apply L2 configuration on the port-channel interface instead.

  • nxos_route_maps - match.metric elements changed from a list of integers to a list of dictionaries with required value and optional deviation (for NX-OS match metric <value> +- <deviation>). Update playbooks from metric: [10, 200] to metric: [{value: 10}, {value: 200}] (or add deviation when needed). Fixes fact-gathering failures on that CLI.

community.okd

community.postgresql

  • postgresql_membership - state=exact now reports granted with an entry for every requested group, as state=present does, so result.granted == {} no longer holds on an unchanged run.

  • postgresql_membership - a memberships row must set granted_by when the connecting role holds ADMIN OPTION on a group only through another role, since PostgreSQL refuses a grant recorded under a role without the option. The deprecated groups option is not affected.

  • postgresql_membership - on PostgreSQL 16 and later a memberships row manages the one grant recorded under its granting role, which is the bootstrap superuser when the connecting role is a superuser, the connecting role otherwise, or the role named by granted_by. state=present makes that grant even when another role has granted the membership, and state=absent and state=exact neither revoke nor report a grant recorded under another role. A task that was unchanged may report changed on its first run and fire its handlers. The deprecated groups option keeps treating the (group, target role) pair as the membership, whoever granted it (https://github.com/ansible-collections/community.postgresql/issues/757).

hetzner.hcloud

  • Drop support for Python 3.10

  • Drop support for ansible-core 2.18

infoblox.nios_modules

  • nios_next_network lookup - the cidr argument is now required and must be an integer. Previously, omitting cidr silently defaulted to 24; playbooks that relied on this default now fail with AnsibleError: missing required argument: cidr. Update such playbooks to pass cidr explicitly (https://github.com/infobloxopen/infoblox-ansible/pull/315).

lowlydba.sqlserver

netapp_eseries.santricity

  • na_santricity_volume and nar_santricity_host - Rename volume option raid_level to ddp_raid_level for dynamic disk pool volumes.

Major Changes

Ansible-core

  • Secret masking - Ansible now automatically redacts known secret values from the output it generates, such as display output (including verbose, warning, deprecation, and error output), module logging, and task results passed to callback plugins. Masking is non-destructive; the real value remains available to tasks, conditionals, and registered variables, only the rendered output is redacted with $REDACTED$.

  • Secret masking - add the ansible.module_utils.secrets public API for working with secrets manually. It provides register_secret and register_secrets to register values that should be redacted from masked output, and mask_secrets to redact any registered secrets from a string. The API can be used on the controller and in Python modules; the new Ansible.Secrets C# module_util provides the equivalent [Ansible.Secrets.SecretMasker]::RegisterSecret() and MaskString() methods for PowerShell modules. Secrets registered inside a module or worker process are propagated back to the controller so they are also masked there.

  • ansible - Add support for Python 3.15.

  • ansible - Drop support for Python 3.12 on the controller.

ansible.mysql

  • MariaDB support is deprecated and is scheduled for removal in version 6.0.0 of this collection. If you already use this collection with MariaDB, please install the ansible.mariadb collection from Ansible Galaxy and change FQCNs in tasks in your playbooks to use ansible.mariadb equivalents, for example, ansible.mysql.mysql_info -> ansible.mariadb.mariadb_info, etc. No other changes are needed. This collection was cloned to the ansible.mariadb collection to allow its contributors and maintainers to focus on MariaDB-related automation development. This ansible.mysql collection still supports MariaDB (only bugfixes and security fixes) until its release 6.0.0 (not earlier than mid 2027), then its support will be dropped!

community.clickhouse

  • clickhouse_named_collection - new module to add/modify/delete named collections in database.

community.vmware

fortinet.fortios

  • Supported multiple versions of log fact modules.

  • Supported new versions 7.6.7 and 8.0.0.

  • Updated the Q&A for importing a certificate in the fortios_certificate_remote module.

netapp.ontap

  • na_ontap_cg_snapshot - AWS Lambda support added to the module.

  • na_ontap_cli_timeout - AWS Lambda support added to the module.

  • na_ontap_ems_config - AWS Lambda support added to the module.

  • na_ontap_ems_destination - AWS Lambda support added to the module.

  • na_ontap_ems_filter - AWS Lambda support added to the module.

  • na_ontap_fdsd - AWS Lambda support added to the module.

  • na_ontap_fdsp - AWS Lambda support added to the module.

  • na_ontap_fdspt - AWS Lambda support added to the module.

  • na_ontap_fdss - AWS Lambda support added to the module.

  • na_ontap_file_security_permissions_acl - AWS Lambda support added to the module.

  • na_ontap_fpolicy_event - AWS Lambda support added to the module.

  • na_ontap_fpolicy_ext_engine - AWS Lambda support added to the module.

  • na_ontap_fpolicy_policy - AWS Lambda support added to the module.

  • na_ontap_fpolicy_scope - AWS Lambda support added to the module.

  • na_ontap_fpolicy_status - AWS Lambda support added to the module.

  • na_ontap_kerberos_interface - AWS Lambda support added to the module.

  • na_ontap_kerberos_realm - AWS Lambda support added to the module.

  • na_ontap_login_messages - AWS Lambda support added to the module.

  • na_ontap_nvme_namespace - AWS Lambda support added to the module.

  • na_ontap_publickey - AWS Lambda support added to the module.

  • na_ontap_rest_cli - AWS Lambda support added to the module.

  • na_ontap_security_key_manager - AWS Lambda support added to the module.

  • na_ontap_security_ssh - AWS Lambda support added to the module.

  • na_ontap_snaplock_clock - AWS Lambda support added to the module.

  • na_ontap_unix_group - AWS Lambda support added to the module.

  • na_ontap_unix_user - AWS Lambda support added to the module.

  • na_ontap_user - AWS Lambda support added to the module.

  • na_ontap_user_role - AWS Lambda support added to the module.

  • na_ontap_vscan - AWS Lambda support added to the module.

  • na_ontap_vscan_on_access_policy - AWS Lambda support added to the module.

  • na_ontap_vscan_on_demand_task - AWS Lambda support added to the module.

  • na_ontap_vscan_scanner_pool - AWS Lambda support added to the module.

  • na_ontap_vserver_audit - AWS Lambda support added to the module.

splunk.es

  • ci - integration tests now run against both Splunk Server 9.4 and 10.4 with Enterprise Security (ES), providing full coverage across supported major versions and catching regressions against real Splunk ES instances.

vmware.vmware_rest

  • Update minimum required ansible-core version to 2.16 in meta/runtime.yml

Removed Collections

  • cyberark.pas (previously included version: 1.0.39)

  • netapp.cloudmanager (previously included version: 21.24.0)

You can still install a removed collection manually with ansible-galaxy collection install <name-of-collection>.

Removed Features

  • The netapp.cloudmanager collection was considered unmaintained and has been removed from Ansible 15 (https://forum.ansible.com/t/44891). Users can still install this collection with ansible-galaxy collection install netapp.cloudmanager.

  • The cyberark.pas collection has been removed from Ansible 15 due to violations of the Ansible inclusion requirements. The collection has violated the inclusion requirements multiple times, including those surrounding repository management. The collection maintainers did not respond to the latest violation report. See Collections Removal Process for collections not satisfying the collection requirements for more details (https://forum.ansible.com/t/45816). Users can still install this collection with ansible-galaxy collection install cyberark.pas.

Ansible-core

  • Remove deprecated ANSIBLE_CONNECTION_PATH option

  • Remove deprecated DEFAULT_LIBVIRT_LXC_NOSECLABEL option.

  • url/uri - remove deprecated use of yes/no values for the follow_redirects option (https://github.com/ansible/ansible/issues/86790)

  • yum_repository - Removed deprecated parameters.

community.postgresql

hetzner.hcloud

  • hcloud inventory - The deprecated hcloud_datacenter host variable was removed. Please use the hcloud_location host variable instead.

  • network_info - The deprecated hcloud_network_info[].servers[].datacenter return value was removed. Please use the hcloud_network_info[].servers[].location return value instead.

  • primary_ip - The deprecated datacenter argument was removed. Please use the location argument instead.

  • primary_ip - The deprecated hcloud_primary_ip.datacenter return value was removed. Please use the hcloud_primary_ip.location return value instead.

  • primary_ip_info - The deprecated hcloud_primary_ip_info[].datacenter return value was removed. Please use the hcloud_primary_ip_info[].location return value instead.

  • server - The deprecated datacenter argument was removed. Please use the location argument instead.

  • server - The deprecated hcloud_server.datacenter return value was removed. Please use the hcloud_server.location return value instead.

  • server_info - The deprecated hcloud_server_info[].datacenter return value was removed. Please use the hcloud_server_info[].location return value instead.

ngine_io.cloudstack

  • The deprecated routing to module names with cs_ prefix has been removed. Use the new module names instead.

Deprecated Features

Ansible-core

  • AGNOSTIC_BECOME_PROMPT setting, no external tools should need this any more.

  • Deprecate is_module in get_docstring API in favor of passing plugin_type='module'.

  • ansible.module_utils.six - A runtime deprecation warning is now emitted when importing the six compatibility library, deprecated in ansible-core 2.21 and planned for removal in ansible-core 2.24 (https://github.com/ansible/ansible/issues/86789).

  • action plugins - AnsibleActionSkip is deprecated and will be removed in ansible-core 2.25. A sanity test detects imports of this exception. Return a results dict from action plugins and don’t include a skipped key, or raise AnsibleActionNoCheckMode if necessary.

  • ansible.utils.cmd_functions.run_cmd - the live argument is deprecated and will be removed in ansible-core 2.25 because it writes the subprocess output directly to stdout/stderr, bypassing the built-in secret masking applied to captured output. Callers that need to stream output live should run the subprocess themselves and are responsible for masking any secrets.

  • module_utils - the heuristic_log_sanitize() function in ansible.module_utils.basic is deprecated and will be removed in ansible-core 2.25. Secret values are now masked automatically, use functions from the ansible.module_utils.secrets module to handle secrets manually.

  • module_utils - the remove_values() and sanitize_keys() functions in ansible.module_utils.common.parameters are deprecated and will be removed in ansible-core 2.25. Secret values are now masked automatically, use functions from the ansible.module_utils.secrets module to handle secrets manually.

  • task result - Returning skipped from a module or action plugin is deprecated and will be removed in ansible-core 2.25. Use task-level conditionals (when:) to control execution.

community.clickhouse

community.crypto

community.general

  • keycloak_authentication - the module is moved to middleware_automation.keycloak.keycloak_authentication. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_authentication_required_actions - the module is moved to middleware_automation.keycloak.keycloak_authentication_required_actions. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_authentication_v2 - the module is moved to middleware_automation.keycloak.keycloak_authentication_v2. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_authz_authorization_scope - the module is moved to middleware_automation.keycloak.keycloak_authz_authorization_scope. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_authz_custom_policy - the module is moved to middleware_automation.keycloak.keycloak_authz_custom_policy. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_authz_permission - the module is moved to middleware_automation.keycloak.keycloak_authz_permission. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_authz_permission_info - the module is moved to middleware_automation.keycloak.keycloak_authz_permission_info. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_client - the module is moved to middleware_automation.keycloak.keycloak_client. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_client_rolemapping - the module is moved to middleware_automation.keycloak.keycloak_client_rolemapping. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_client_rolescope - the module is moved to middleware_automation.keycloak.keycloak_client_rolescope. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_clientscope - the module is moved to middleware_automation.keycloak.keycloak_client_scope. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_clientscope_rolemappings - the module is moved to middleware_automation.keycloak.keycloak_client_scope_rolemappings. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_clientscope_type - the module is moved to middleware_automation.keycloak.keycloak_client_scope_type. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_clientsecret_info - the module is moved to middleware_automation.keycloak.keycloak_clientsecret_info. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_clientsecret_regenerate - the module is moved to middleware_automation.keycloak.keycloak_clientsecret_regenerate. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_clienttemplate - the module is moved to middleware_automation.keycloak.keycloak_clienttemplate. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_component - the module is moved to middleware_automation.keycloak.keycloak_component. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_component_info - the module is moved to middleware_automation.keycloak.keycloak_component_info. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_group - the module is moved to middleware_automation.keycloak.keycloak_group. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_identity_provider - the module is moved to middleware_automation.keycloak.keycloak_identity_provider. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_realm - the module is moved to middleware_automation.keycloak.keycloak_realm. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_realm_key - the module is moved to middleware_automation.keycloak.keycloak_realm_key. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_realm_keys_metadata_info - the module is moved to middleware_automation.keycloak.keycloak_realm_keys_metadata_info. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_realm_localization - the module is moved to middleware_automation.keycloak.keycloak_realm_localization. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_realm_rolemapping - the module is moved to middleware_automation.keycloak.keycloak_realm_rolemapping. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_realm_users_info - the module is moved to middleware_automation.keycloak.keycloak_realm_users_info. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using ansible_middleware.keycloak now (https://github.com/ansible-collections/community.general/pull/12525).

  • keycloak_role - the module is moved to middleware_automation.keycloak.keycloak_role. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_user - the module is moved to middleware_automation.keycloak.keycloak_user. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_user_execute_actions_email - the module is moved to middleware_automation.keycloak.keycloak_user_execute_actions_email. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_user_federation - the module is moved to middleware_automation.keycloak.keycloak_user_federation. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_user_rolemapping - the module is moved to middleware_automation.keycloak.keycloak_user_rolemapping. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

  • keycloak_userprofile - the module is moved to middleware_automation.keycloak.keycloak_userprofile. The module will be replaced by a deprecated redirect to that module in community.general 14.0.0, and the redirect will be removed in community.general 16.0.0. If you are using the module, please consider installing and using middleware_automation.keycloak now (https://github.com/ansible-collections/community.general/pull/12484).

community.postgresql

  • postgresql_membership - the top-level groups option is deprecated and will be removed in community.postgresql 6.0.0. granted_by_any with the groups key of memberships behaves the same on every version; target_roles stays at the top level, and an empty memberships list with state=exact replaces an empty groups list.

community.rabbitmq

community.vmware

hetzner.hcloud

  • datacenter_info - The datacenter_info module is deprecated and will be removed after 1 Oct. 2026. Please use the location_info module instead.

kubernetes.core

netapp_eseries.santricity

  • na_santricity_volume and nar_santricity_host - The raid_level volume option alias is deprecated and will be removed in version 3.0.0. Use ddp_raid_level instead.

purestorage.flashblade

  • purefb_fs - The nfs_rules parameter is deprecated in favour of export_policy and will be removed in 2.0.0. A deprecation notice is emitted when it is used.

theforeman.foreman

vmware.vmware_rest