Ansible 2.9 Porting Guide

This section discusses the behavioral changes between Ansible 2.8 and Ansible 2.9.

It is intended to assist in updating your playbooks, plugins and other parts of your Ansible infrastructure so they will work with this version of Ansible.

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

This document is part of a collection on porting. The complete list of porting guides can be found at porting guides.

Playbook

Inventory

  • hash_behaviour now affects inventory sources. If you have it set to merge, the data you get from inventory might change and you will have to update playbooks accordingly. If you’re using the default setting (overwrite), you will see no changes. Inventory was ignoring this setting.

Loops

Ansible 2.9 handles “unsafe” data more robustly, ensuring that data marked “unsafe” is not templated. In previous versions, Ansible recursively marked all data returned by the direct use of lookup() as “unsafe”, but only marked structured data returned by indirect lookups using with_X style loops as “unsafe” if the returned elements were strings. Ansible 2.9 treats these two approaches consistently.

As a result, if you use with_dict to return keys with templatable values, your templates may no longer work as expected in Ansible 2.9.

To allow the old behavior, switch from using with_X to using loop with a filter as described at Migrating from with_X to loop.

Command Line

  • The location of the Galaxy token file has changed from ~/.ansible_galaxy to ~/.ansible/galaxy_token. You can configure both path and file name with the GALAXY_TOKEN_PATH config.

Deprecated

  • The params module option in ldap_attr and ldap_entry are deprecated on a short cycle (to be removed in Ansible-2.10) due to circumventing Ansible’s normal option handling. In particular, if the bind_pw option is set with params, the value of the option could end up being placed in a logfile or displayed on stdout.

Collection loader changes

The way to import a PowerShell or C# module util from a collection has changed in the Ansible 2.9 release. In Ansible 2.8 a util was imported with the following syntax:

#AnsibleRequires -CSharpUtil AnsibleCollections.namespace_name.collection_name.util_filename
#AnsibleRequires -PowerShell AnsibleCollections.namespace_name.collection_name.util_filename

In Ansible 2.9 this was changed to:

#AnsibleRequires -CSharpUtil ansible_collections.namespace_name.collection_name.plugins.module_utils.util_filename
#AnsibleRequires -PowerShell ansible_collections.namespace_name.collection_name.plugins.module_utils.util_filename

The change in the collection import name also requires any C# util namespaces to be updated with the newer name format. This is more verbose but is designed to make sure we avoid plugin name conflicts across separate plugin types and to standardise how imports work in PowerShell with how Python modules work.

Modules

  • The win_get_url and win_uri module now sends requests with a default User-Agent of ansible-httpget. This can be changed by using the http_agent key.
  • The apt module now honors update_cache=false while installing its own dependency and skips the cache update. Explicitly setting update_cache=true or omitting the param update_cache will result in a cache update while installing its own dependency.

Renaming from _facts to _info

Ansible 2.9 renamed a lot of modules from <something>_facts to <something>_info, because the modules do not return Ansible facts. Ansible facts relate to a specific host. For example, the configuration of a network interface, the operating system on a unix server, and the list of packages installed on a Windows box are all Ansible facts. The renamed modules return values that are not unique to the host. For example, account information or region data for a cloud provider. Renaming these modules should provide more clarity about the types of return values each set of modules offers.

Writing modules

  • Module and module_utils files can now use relative imports to include other module_utils files. This is useful for shortening long import lines, especially in collections.

    Example of using a relative import in collections:

    # File: ansible_collections/my_namespace/my_collection/plugins/modules/my_module.py
    # Old way to use an absolute import to import module_utils from the collection:
    from ansible_collections.my_namespace.my_collection.plugins.module_utils import my_util
    # New way using a relative import:
    from ..module_utils import my_util
    

    Modules and module_utils shipped with Ansible can use relative imports as well but the savings are smaller:

    # File: ansible/modules/system/ping.py
    # Old way to use an absolute import to import module_utils from core:
    from ansible.module_utils.basic import AnsibleModule
    # New way using a relative import:
    from ...module_utils.basic import AnsibleModule
    

    Each single dot (.) represents one level of the tree (equivalent to ../ in filesystem relative links).

    See also

    The Python Relative Import Docs go into more detail of how to write relative imports.

Modules removed

The following modules no longer exist:

Deprecation notices

The following modules will be removed in Ansible 2.13. Please update update your playbooks accordingly.

The following functionality will be removed in Ansible 2.12. Please update update your playbooks accordingly.

The following functionality will be removed in Ansible 2.13. Please update update your playbooks accordingly.

For the following modules, the PyOpenSSL-based backend pyopenssl has been deprecated and will be removed in Ansible 2.13:

Renamed modules

The following modules have been renamed. The old name is deprecated and will be removed in Ansible 2.13. Please update update your playbooks accordingly.

Noteworthy module changes

  • Security Issue Setting bind_pw with the params option for the ldap_entry and ldap_attr modules has been disallowed. If bind_pw was set with params, the value could have ended up in a logfile or displayed on stdout. Set bind_pw directly, with the modules’ options instead.
  • vmware_cluster was refactored for easier maintenance/bugfixes. Use the three new, specialized modules to configure clusters. Configure DRS with vmware_cluster_drs, HA with vmware_cluster_ha and vSAN with vmware_cluster_vsan.
  • vmware_dvswitch accepts folder parameter to place dvswitch in user defined folder. This option makes datacenter as an optional parameter.
  • vmware_datastore_cluster accepts folder parameter to place datastore cluster in user defined folder. This option makes datacenter as an optional parameter.
  • mysql_db returns new db_list parameter in addition to db parameter. This db_list parameter refers to list of database names. db parameter will be deprecated in version 2.13.
  • snow_record and snow_record_find now takes environment variables for instance, username and password parameters. This change marks these parameters as optional.
  • The deprecated force option in win_firewall_rule has been removed.
  • openssl_certificate’s ownca provider creates authority key identifiers if not explicitly disabled with ownca_create_authority_key_identifier: no. This is only the case for the cryptography backend, which is selected by default if the cryptography library is available.
  • openssl_certificate’s ownca and selfsigned providers create subject key identifiers if not explicitly disabled with ownca_create_subject_key_identifier: never_create resp. selfsigned_create_subject_key_identifier: never_create. If a subject key identifier is provided by the CSR, it is taken; if not, it is created from the public key. This is only the case for the cryptography backend, which is selected by default if the cryptography library is available.
  • openssh_keypair now applies the same file permissions and ownership to both public and private keys (both get the same mode, owner, group, etc.). If you need to change permissions / ownership on one key, use the file to modify it after it is created.
  • acme_certificate only returns challenges that need to be satisfied in challenge_data and challenge_data_dns (since Ansible 2.8.5). Depending on how you process challenges, you need to adjust your challenge satisfying tasks to either use when: to only process domain names which appear in challenge_data, or by looping over the challenge_data dictionary itself. See the updated examples in the module documentation.

Plugins

Removed Lookup Plugins

  • redis_kv use redis instead.

Porting custom scripts

No notable changes

Networking

Network resource modules

Ansible 2.9 introduced the first batch of network resource modules. Sections of a network device’s configuration can be thought of as a resource provided by that device. Network resource modules are intentionally scoped to configure a single resource and you can combine them as building blocks to configure complex network services. The older modules are deprecated in Ansible 2.9 and will be removed in Ansible 2.13. You should scan the list of deprecated modules above and replace them with the new network resource modules in your playbooks. See Ansible Network Features in 2.9 for details.

Improved gather_facts support for network devices

In Ansible 2.9, the gather_facts keyword now supports gathering network device facts in standardized key/value pairs. You can feed these network facts into further tasks to manage the network device. You can also use the new gather_network_resources parameter with the network *_facts modules (such as eos_facts) to return just a subset of the device configuration. See Gathering facts from network devices for an example.

Top-level connection arguments removed in 2.9

Top-level connection arguments like username, host, and password are removed in version 2.9.

OLD In Ansible < 2.4

- name: example of using top-level options for connection properties
  ios_command:
    commands: show version
    host: "{{ inventory_hostname }}"
    username: cisco
    password: cisco
    authorize: yes
    auth_pass: cisco

Change your playbooks to the connection types network_cli and netconf using standard Ansible connection properties, and setting those properties in inventory by group. As you update your playbooks and inventory files, you can easily make the change to become for privilege escalation (on platforms that support it). For more information, see the using become with network modules guide and the platform documentation.