diff --git a/docs/docsite/rst/index.rst b/docs/docsite/rst/index.rst index eea338480cd1f4..4c99b5024940e8 100644 --- a/docs/docsite/rst/index.rst +++ b/docs/docsite/rst/index.rst @@ -12,13 +12,13 @@ Ansible's main goals are simplicity and ease-of-use. It also has a strong focus We believe simplicity is relevant to all sizes of environments, so we design for busy users of all types: developers, sysadmins, release engineers, IT managers, and everyone in between. Ansible is appropriate for managing all environments, from small setups with a handful of instances to enterprise environments with many thousands of instances. -Ansible manages machines in an agent-less manner. There is never a question of how to -upgrade remote daemons or the problem of not being able to manage systems because daemons are uninstalled. Because OpenSSH is one of the most peer-reviewed open source components, security exposure is greatly reduced. Ansible is decentralized--it relies on your existing OS credentials to control access to remote machines. If needed, Ansible can easily connect with Kerberos, LDAP, and other centralized authentication management systems. +You can learn more at `AnsibleFest `_, the annual event for all Ansible contributors, users, and customers hosted by Red Hat. AnsibleFest is the place to connect with others, learn new skills, and find a new friend to automate with. -This documentation covers the version of Ansible noted in the upper left corner of this page. We maintain multiple versions of Ansible and of the documentation, so please be sure you are using the version of the documentation that covers the version of Ansible you're using. For recent features, we note the version of Ansible where the feature was added. +Ansible manages machines in an agent-less manner. There is never a question of how to upgrade remote daemons or the problem of not being able to manage systems because daemons are uninstalled. Because OpenSSH is one of the most peer-reviewed open source components, security exposure is greatly reduced. Ansible is decentralized--it relies on your existing OS credentials to control access to remote machines. If needed, Ansible can easily connect with Kerberos, LDAP, and other centralized authentication management systems. -Ansible releases a new major release of Ansible approximately three to four times per year. The core application evolves somewhat conservatively, valuing simplicity in language design and setup. However, the community around new modules and plugins being developed and contributed moves very quickly, adding many new modules in each release. +This documentation covers the version of Ansible noted in the upper left corner of this page. We maintain multiple versions of Ansible and of the documentation, so please be sure you are using the version of the documentation that covers the version of Ansible you're using. For recent features, we note the version of Ansible where the feature was added. +Ansible releases a new major release of Ansible approximately three to four times per year. The core application evolves somewhat conservatively, valuing simplicity in language design and setup. Contributors develop and change modules and plugins, hosted in collections since version 2.10, much more quickly. .. toctree:: :maxdepth: 2 diff --git a/docs/docsite/rst/network/user_guide/network_resource_modules.rst b/docs/docsite/rst/network/user_guide/network_resource_modules.rst index e7bc2e1b6a2bb3..f868464ddb501f 100644 --- a/docs/docsite/rst/network/user_guide/network_resource_modules.rst +++ b/docs/docsite/rst/network/user_guide/network_resource_modules.rst @@ -150,6 +150,50 @@ The following playbook uses the :ref:`eos_l3_interfaces `_ diff --git a/docs/docsite/rst/plugins/cliconf.rst b/docs/docsite/rst/plugins/cliconf.rst index 1d888c6b6c8935..df6d1921b57b6c 100644 --- a/docs/docsite/rst/plugins/cliconf.rst +++ b/docs/docsite/rst/plugins/cliconf.rst @@ -9,7 +9,7 @@ Cliconf Plugins .. warning:: - Links on this page may not point to the most recent versions of plugins. In preparation for the release of 2.10, many plugins and modules have migrated to Collections on `Ansible Galaxy `_. For the current development status of Collections and FAQ see `Ansible Collections Community Guide `_. + Links on this page may not point to the most recent versions of plugins. In preparation for the release of 2.10, many plugins and modules have migrated to Collections on `Ansible Galaxy `_. For the current development status of Collections and FAQ see `Ansible Collections Community Guide `_. Cliconf plugins are abstractions over the CLI interface to network devices. They provide a standard interface for Ansible to execute tasks on those network devices. diff --git a/docs/docsite/rst/plugins/httpapi.rst b/docs/docsite/rst/plugins/httpapi.rst index 1b5554d1421a30..38099cb3ef0214 100644 --- a/docs/docsite/rst/plugins/httpapi.rst +++ b/docs/docsite/rst/plugins/httpapi.rst @@ -9,7 +9,7 @@ Httpapi Plugins .. warning:: - Links on this page may not point to the most recent versions of plugins. In preparation for the release of 2.10, many plugins and modules have migrated to Collections on `Ansible Galaxy `_. For the current development status of Collections and FAQ see `Ansible Collections Community Guide `_. + Links on this page may not point to the most recent versions of plugins. In preparation for the release of 2.10, many plugins and modules have migrated to Collections on `Ansible Galaxy `_. For the current development status of Collections and FAQ see `Ansible Collections Community Guide `_. Httpapi plugins tell Ansible how to interact with a remote device's HTTP-based API and execute tasks on the device. diff --git a/docs/docsite/rst/plugins/netconf.rst b/docs/docsite/rst/plugins/netconf.rst index 6611dbd41a26f9..64030cc6e995c7 100644 --- a/docs/docsite/rst/plugins/netconf.rst +++ b/docs/docsite/rst/plugins/netconf.rst @@ -9,7 +9,7 @@ Netconf Plugins .. warning:: - Links on this page may not point to the most recent versions of plugins. In preparation for the release of 2.10, many plugins and modules have migrated to Collections on `Ansible Galaxy `_. For the current development status of Collections and FAQ see `Ansible Collections Community Guide `_. + Links on this page may not point to the most recent versions of plugins. In preparation for the release of 2.10, many plugins and modules have migrated to Collections on `Ansible Galaxy `_. For the current development status of Collections and FAQ see `Ansible Collections Community Guide `_. Netconf plugins are abstractions over the Netconf interface to network devices. They provide a standard interface for Ansible to execute tasks on those network devices. diff --git a/docs/docsite/rst/porting_guides/porting_guide_base_2.10.rst b/docs/docsite/rst/porting_guides/porting_guide_base_2.10.rst index 2d51bb95700dc1..20f3fb538da591 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_base_2.10.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_base_2.10.rst @@ -152,9 +152,3 @@ Porting custom scripts ====================== No notable changes - - -Networking -========== - -No notable changes diff --git a/docs/docsite/rst/reference_appendices/release_and_maintenance.rst b/docs/docsite/rst/reference_appendices/release_and_maintenance.rst index e8fa22fa72773b..5f643d9841be26 100644 --- a/docs/docsite/rst/reference_appendices/release_and_maintenance.rst +++ b/docs/docsite/rst/reference_appendices/release_and_maintenance.rst @@ -3,21 +3,21 @@ Release and maintenance ======================= +This section describes the Ansible and ``ansible-base`` releases. Ansible is the package that most users install. ``ansible-base`` is primarily for developers. + .. contents:: :local: .. _release_cycle: -Release cycle -````````````` +Ansible release cycle +----------------------- -Ansible is developed and released on a flexible six month release cycle. +Ansible is developed and released on a flexible release cycle. This cycle can be extended in order to allow for larger changes to be properly -implemented and tested before a new release is made available. +implemented and tested before a new release is made available. See :ref:`roadmaps` for upcoming release details. -Ansible has a graduated maintenance structure that extends to three major releases. -For more information, read about the :ref:`development_and_stable_version_maintenance_workflow` or -see the chart in :ref:`release_schedule` for the degrees to which current releases are maintained. +For Ansible version 2.10 or later, the major release is maintained for one release cycle. When the next release comes out (for example, 2.11), the older release (2.10 in this example) is no longer maintained. If you are using a release of Ansible that is no longer maintained, we strongly encourage you to upgrade as soon as possible in order to benefit from the @@ -27,34 +27,29 @@ Older, unmaintained versions of Ansible can contain unfixed security vulnerabilities (*CVE*). You can refer to the :ref:`porting guides` for tips on updating your Ansible -playbooks to run on newer versions. +playbooks to run on newer versions. You can download the Ansible release from ``_. -.. _release_schedule: -Release status -`````````````` -This table links to the release notes for each major release. These release notes (changelogs) contain the dates and significant changes in each minor release. - -============================== ================================================= -Ansible Release Status -============================== ================================================= -devel In development (2.10 unreleased, trunk) -`2.9 Release Notes`_ Maintained (security **and** general bug fixes) -`2.8 Release Notes`_ Maintained (security **and** critical bug fixes) -`2.7 Release Notes`_ Maintained (security fixes) -`2.6 Release Notes`_ Unmaintained (end of life) -`2.5 Release Notes`_ Unmaintained (end of life) -<2.5 Unmaintained (end of life) -============================== ================================================= - -You can download the releases from ``_. - -.. note:: Ansible maintenance continues for 3 releases. Thus the latest Ansible release receives - security and general bug fixes when it is first released, security and critical bug fixes when - the next Ansible version is released, and **only** security fixes once the follow on to that version is released. +This table links to the release notes for each major Ansible release. These release notes (changelogs) contain the dates and significant changes in each minor release. + +================================== ================================================= +Ansible Release Status +================================== ================================================= +devel In development (2.11 unreleased, trunk) +`2.10 Release Notes`_ In development (2.10 alpha/beta) +`2.9 Release Notes`_ Maintained (security **and** general bug fixes) +`2.8 Release Notes`_ Maintained (security fixes) +`2.7 Release Notes`_ Unmaintained (end of life) +`2.6 Release Notes`_ Unmaintained (end of life) +`2.5 Release Notes`_ Unmaintained (end of life) +<2.5 Unmaintained (end of life) +================================== ================================================= + .. Comment: devel used to point here but we're currently revamping our changelog process and have no link to a static changelog for devel _2.6: https://github.com/ansible/ansible/blob/devel/CHANGELOG.md +.. _2.10 Release Notes: +.. _2.10: https://github.com/ansible-community/ansible-build-data/blob/main/2.10/CHANGELOG-v2.10.rst .. _2.9 Release Notes: .. _2.9: https://github.com/ansible/ansible/blob/stable-2.9/changelogs/CHANGELOG-v2.9.rst .. _2.8 Release Notes: @@ -64,28 +59,71 @@ You can download the releases from ``_. .. _2.6: https://github.com/ansible/ansible/blob/stable-2.6/changelogs/CHANGELOG-v2.6.rst .. _2.5 Release Notes: https://github.com/ansible/ansible/blob/stable-2.5/changelogs/CHANGELOG-v2.5.rst + +ansible-base release cycle +------------------------------- + +``ansible-base`` is developed and released on a flexible release cycle. +This cycle can be extended in order to allow for larger changes to be properly +implemented and tested before a new release is made available. See :ref:`roadmaps` for upcoming release details. + +``ansible-base`` has a graduated maintenance structure that extends to three major releases. +For more information, read about the :ref:`development_and_stable_version_maintenance_workflow` or +see the chart in :ref:`release_schedule` for the degrees to which current releases are maintained. + +If you are using a release of ``ansible-base`` that is no longer maintained, we strongly +encourage you to upgrade as soon as possible in order to benefit from the +latest features and security fixes. + +Older, unmaintained versions of ``ansible-base`` can contain unfixed security +vulnerabilities (*CVE*). + +You can refer to the :ref:`porting guides` for tips on updating your Ansible +playbooks to run on newer versions. + +You can download the ``ansible-base`` release from ``_. + +.. note:: ``ansible-base`` maintenance continues for 3 releases. Thus the latest release receives + security and general bug fixes when it is first released, security and critical bug fixes when + the next ``ansible-base`` version is released, and **only** security fixes once the follow on to that version is released. + + +.. _release_schedule: + + +This table links to the release notes for each major ``ansible-base`` release. These release notes (changelogs) contain the dates and significant changes in each minor release. + +================================== ================================================= + ``ansible-base`` Release Status +================================== ================================================= +devel In development (2.11 unreleased, trunk) +`2.10 ansible-base Release Notes`_ Maintained (security **and** general bug fixes) +================================== ================================================= + + +.. _2.10 ansible-base Release Notes: +.. _2.10-base: https://github.com/ansible/ansible/blob/stable-2.10/changelogs/CHANGELOG-v2.10.rst .. _support_life: .. _methods: .. _development_and_stable_version_maintenance_workflow: Development and stable version maintenance workflow -``````````````````````````````````````````````````` +----------------------------------------------------- -The Ansible community develops and maintains Ansible on GitHub_. +The Ansible community develops and maintains Ansible and ``ansible-base`` on GitHub_. -New modules, plugins, features and bugfixes will always be integrated in what will become the next -major version of Ansible. This work is tracked on the ``devel`` git branch. +Collection updates (new modules, plugins, features and bugfixes) will always be integrated in what will become the next version of Ansible. This work is tracked within the individual collection repositories. -Ansible provides bugfixes and security improvements for the most recent major release. The previous -major release will only receive fixes for security issues and critical bugs. Ansible only applies +Ansible and ``ansible-base`` provide bugfixes and security improvements for the most recent major release. The previous +major release of ``ansible-base`` will only receive fixes for security issues and critical bugs.``ansible-base`` only applies security fixes to releases which are two releases old. This work is tracked on the ``stable-`` git branches. The fixes that land in maintained stable branches will eventually be released as a new version when necessary. -Note that while there are no guarantees for providing fixes for Unmaintained +Note that while there are no guarantees for providing fixes for unmaintained releases of Ansible, there can sometimes be exceptions for critical issues. .. _GitHub: https://github.com/ansible/ansible @@ -93,25 +131,23 @@ releases of Ansible, there can sometimes be exceptions for critical issues. .. _release_changelogs: Changelogs -~~~~~~~~~~ +^^^^^^^^^^^^ -Since Ansible 2.5, we have generated changelogs based on fragments. Here is the generated changelog for 2.9_ as an example. When creating new features or fixing bugs, create a changelog fragment describing the change. A changelog entry is not needed for new modules or plugins. Details for those items will be generated from the module documentation. +We generate changelogs based on fragments. Here is the generated changelog for 2.9_ as an example. When creating new features or fixing bugs, create a changelog fragment describing the change. A changelog entry is not needed for new modules or plugins. Details for those items will be generated from the module documentation. We've got :ref:`examples and instructions on creating changelog fragments ` in the Community Guide. -Older versions logged changes in ``stable-`` branches at ``stable-/CHANGELOG.md``. For example, here is the changelog for `2.4 `_ on GitHub. - Release candidates -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^ -Before a new release or version of Ansible can be done, it will typically go +Before a new release or version of Ansible or ``ansible-base`` can be done, it will typically go through a release candidate process. -This provides the Ansible community the opportunity to test Ansible and report +This provides the Ansible community the opportunity to test these releases and report bugs or issues they might come across. -Ansible tags the first release candidate (``RC1``) which is usually scheduled +Ansible and ``ansible-base`` tag the first release candidate (``RC1``) which is usually scheduled to last five business days. The final release is done if no major bugs or issues are identified during this period. @@ -122,13 +158,13 @@ If no problems have been reported after two business days, the final release is done. More release candidates can be tagged as required, so long as there are -bugs that the Ansible core maintainers consider should be fixed before the +bugs that the Ansible or ``ansible-base`` core maintainers consider should be fixed before the final release. .. _release_freezing: Feature freeze -~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^ While there is a pending release candidate, the focus of core developers and maintainers will on fixes towards the release candidate. @@ -138,13 +174,21 @@ be delayed in order to allow the new release to be shipped as soon as possible. Deprecation Cycle -````````````````` +------------------ Sometimes we need to remove a feature, normally in favor of a reimplementation that we hope does a better job. To do this we have a deprecation cycle. First we mark a feature as 'deprecated'. This is normally accompanied with warnings to the user as to why we deprecated it, what alternatives they should switch to and when (which version) we are scheduled to remove the feature permanently. +Ansible deprecation cycle +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Since Ansible is a package of individual collections, the deprecation cycle depends on the collection maintainers. We recommend the collection maintainers deprecate a feature in one Ansible major version and do not remove that feature for one year, or at least until the next major Ansible version. For example, deprecate the feature in 2.10.2, and do not remove the feature until 2.12.0. Collections should use semantic versioning, such that the major collection version cannot be changed within an Ansible major version. Thus the removal should not happen before the next major Ansible release. This is up to each collection maintainer and cannot be guaranteed. + +ansible-base deprecation cycle +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + The cycle is normally across 4 feature releases (2.x.y, where the x marks a feature release and the y a bugfix release), so the feature is normally removed in the 4th release after we announce the deprecation. For example, something deprecated in 2.7 will be removed in 2.11, assuming we don't jump to 3.x before that point. diff --git a/docs/docsite/rst/reference_appendices/special_variables.rst b/docs/docsite/rst/reference_appendices/special_variables.rst index 53ad4b9f5d68e3..7b4fbf818e917c 100644 --- a/docs/docsite/rst/reference_appendices/special_variables.rst +++ b/docs/docsite/rst/reference_appendices/special_variables.rst @@ -51,7 +51,7 @@ ansible_play_batch List of active hosts in the current play run limited by the serial, aka 'batch'. Failed/Unreachable hosts are not considered 'active'. ansible_play_hosts - The same as ansible_play_batch + List of hosts in the current play run, not limited by the serial. Failed/Unreachable hosts are included in this list. ansible_play_hosts_all List of all the hosts that were targeted by the play diff --git a/docs/docsite/rst/scenario_guides/guide_packet.rst b/docs/docsite/rst/scenario_guides/guide_packet.rst index e1f36e7161aed8..74793c579bdc3a 100644 --- a/docs/docsite/rst/scenario_guides/guide_packet.rst +++ b/docs/docsite/rst/scenario_guides/guide_packet.rst @@ -208,9 +208,9 @@ Dynamic Inventory Script The dynamic inventory script queries the Packet API for a list of hosts, and exposes it to Ansible so you can easily identify and act on Packet devices. -You can find it in Ansible Community General Collection's git repo at `scripts/inventory/packet_net.py `_. +You can find it in Ansible Community General Collection's git repo at `scripts/inventory/packet_net.py `_. -The inventory script is configurable via a `ini file `_. +The inventory script is configurable via a `ini file `_. If you want to use the inventory script, you must first export your Packet API token to a PACKET_API_TOKEN environment variable. @@ -218,9 +218,9 @@ You can either copy the inventory and ini config out from the cloned git repo, o .. code-block:: bash - $ wget https://raw.githubusercontent.com/ansible-collections/community.general/master/scripts/inventory/packet_net.py + $ wget https://raw.githubusercontent.com/ansible-collections/community.general/main/scripts/inventory/packet_net.py $ chmod +x packet_net.py - $ wget https://raw.githubusercontent.com/ansible-collections/community.general/master/scripts/inventory/packet_net.ini + $ wget https://raw.githubusercontent.com/ansible-collections/community.general/main/scripts/inventory/packet_net.ini In order to understand what the inventory script gives to Ansible you can run: diff --git a/docs/docsite/rst/user_guide/collections_using.rst b/docs/docsite/rst/user_guide/collections_using.rst index c3f8e6bb7bfc37..0a040c7391ac0a 100644 --- a/docs/docsite/rst/user_guide/collections_using.rst +++ b/docs/docsite/rst/user_guide/collections_using.rst @@ -10,7 +10,7 @@ Collections are a distribution format for Ansible content that can include playb You can install and use collections through `Ansible Galaxy `_. * For details on how to *develop* collections see :ref:`developing_collections`. -* For the current development status of Collections and FAQ see `Ansible Collections Community Guide `_. +* For the current development status of Collections and FAQ see `Ansible Collections Community Guide `_. .. contents:: :local: diff --git a/docs/docsite/rst/user_guide/complex_data_manipulation.rst b/docs/docsite/rst/user_guide/complex_data_manipulation.rst new file mode 100644 index 00000000000000..b9900b50105920 --- /dev/null +++ b/docs/docsite/rst/user_guide/complex_data_manipulation.rst @@ -0,0 +1,243 @@ +.. _complex_data_manipulation: + +Data manipulation +######################### + +In many cases, you need to do some complex operation with your variables, while Ansible is not recommended as a data processing/manipulation tool, you can use the existing Jinja2 templating in conjunction with the many added Ansible filters, lookups and tests to do some very complex transformations. + +Let's start with a quick definition of each type of plugin: + - lookups: Mainly used to query 'external data', in Ansible these were the primary part of loops using the ``with_`` construct, but they can be used independently to return data for processing. They normally return a list due to their primary function in loops as mentioned previously. Used with the ``lookup`` or ``query`` Jinja2 operators. + - filters: used to change/transform data, used with the ``|`` Jinja2 operator. + - tests: used to validate data, used with the ``is`` Jinja2 operator. + +.. _note: + * Some tests and filters are provided directly by Jinja2, so their availability depends on the Jinja2 version, not Ansible. + +.. _for_loops_or_list_comprehensions: + +Loops and list comprehensions +============================= + +Most programming languages have loops (``for``, ``while``, etc.) and list comprehensions to do transformations on lists including lists of objects. Jinja2 has a few filters that provide this functionality: ``map``, ``select``, ``reject``, ``selectattr``, ``rejectattr``. + +- map: this is a basic for loop that just allows you to change every item in a list, using the 'attribute' keyword you can do the transformation based on attributes of the list elements. +- select/reject: this is a for loop with a condition, that allows you to create a subset of a list that matches (or not) based on the result of the condition. +- selectattr/rejectattr: very similar to the above but it uses a specific attribute of the list elements for the conditional statement. + + +.. _keys_from_dict_matching_list: + +Extract keys from a dictionary matching elements from a list +------------------------------------------------------------ + +The Python equivalent code would be: + +.. code-block:: python + + chains = [1, 2] + for chain in chains: + for config in chains_config[chain]['configs']: + print(config['type']) + +There are several ways to do it in Ansible, this is just one example: + +.. code-block:: YAML+Jinja + :emphasize-lines: 3 + :caption: Way to extract matching keys from a list of dictionaries + + tasks: + - name: Show extracted list of keys from a list of dictionaries + debug: msg="{{ chains | map('extract', chains_config) | map(attribute='configs') | flatten | map(attribute='type') | flatten }}" + vars: + chains: [1, 2] + chains_config: + 1: + foo: bar + configs: + - type: routed + version: 0.1 + - type: bridged + version: 0.2 + 2: + foo: baz + configs: + - type: routed + version: 1.0 + - type: bridged + version: 1.1 + + +.. code-block:: ansible-output + :caption: Results of debug task, a list with the extracted keys + + ok: [localhost] => { + "msg": [ + "routed", + "bridged", + "routed", + "bridged" + ] + } + + +.. _find_mount_point: + +Find mount point +---------------- + +In this case, we want to find the mount point for a given path across our machines, since we already collect mount facts, we can use the following: + +.. code-block:: YAML+Jinja + :caption: Use selectattr to filter mounts into list I can then sort and select the last from + :emphasize-lines: 7 + + - hosts: all + gather_facts: True + vars: + path: /var/lib/cache + tasks: + - name: The mount point for {{path}}, found using the Ansible mount facts, [-1] is the same as the 'last' filter + debug: msg="{{(ansible_facts.mounts | selectattr('mount', 'in', path) | list | sort(attribute='mount'))[-1]['mount']}}" + + + +Omit elements from a list +------------------------- + +The special ``omit`` variable ONLY works with module options, but we can still use it in other ways as an identifier to tailor a list of elements: + +.. code-block:: YAML+Jinja + :caption: Inline list filtering when feeding a module option + :emphasize-lines: 3, 7 + + - name: enable a list of Windows features, by name + set_fact: + win_feature_list: "{{ namestuff | reject('equalto', omit) | list }}" + vars: + namestuff: + - "{{ (fs_installed_smb_v1 | default(False)) | ternary(omit, 'FS-SMB1') }}" + - "foo" + - "bar" + + +Another way is to avoid adding elements to the list in the first place, so you can just use it directly: + +.. code-block:: YAML+Jinja + :caption: Using set_fact in a loop to increment a list conditionally + :emphasize-lines: 3, 4, 6 + + - name: build unique list with some items conditionally omittted + set_fact: + namestuff: ' {{ (namestuff | default([])) | union([item]) }}' + when: item != omit + loop: + - "{{ (fs_installed_smb_v1 | default(False)) | ternary(omit, 'FS-SMB1') }}" + - "foo" + - "bar" + + +.. _complex_type_transfomations: + +Complex Type transformations +============================= + +Jinja provides filters for simple data type transformations (``int``, ``bool``, etc), but when you want to transform data structures things are not as easy. +You can use loops and list comprehensions as shown above to help, also other filters and lookups can be chained and leveraged to achieve more complex transformations. + + +.. _create_dictionary_from_list: + +Create dictionary from list +--------------------------- + +In most languages it is easy to create a dictionary (a.k.a. map/associative array/hash etc.) from a list of pairs, in Ansible there are a couple of ways to do it and the best one for you might depend on the source of your data. + + +These example produces ``{"a": "b", "c": "d"}`` + +.. code-block:: YAML+Jinja + :caption: Simple list to dict by assuming the list is [key, value , key, value, ...] + + vars: + single_list: [ 'a', 'b', 'c', 'd' ] + mydict: "{{ dict(single_list) | slice(2) | list }}" + + +.. code-block:: YAML+Jinja + :caption: It is simpler when we have a list of pairs: + + vars: + list_of_pairs: [ ['a', 'b'], ['c', 'd'] ] + mydict: "{{ dict(list_of_pairs) }}" + +Both end up being the same thing, with the ``slice(2) | list`` transforming ``single_list`` to the same structure as ``list_of_pairs``. + + + +A bit more complex, using ``set_fact`` and a ``loop`` to create/update a dictionary with key value pairs from 2 lists: + +.. code-block:: YAML+Jinja + :caption: Using set_fact to create a dictionary from a set of lists + :emphasize-lines: 3, 4 + + - name: Uses 'combine' to update the dictionary and 'zip' to make pairs of both lists + set_fact: + mydict: "{{ mydict | default({}) | combine({item[0]: item[1]}) }}" + loop: "{{ (keys | zip(values)) | list }}" + vars: + keys: + - foo + - var + - bar + values: + - a + - b + - c + +This results in ``{"foo": "a", "var": "b", "bar": "c"}``. + + +You can even combine these simple examples with other filters and lookups to create a dictionary dynamically by matching patterns to variable names: + +.. code-block:: YAML+Jinja + :caption: Using 'vars' to define dictionary from a set of lists without needing a task + + vars: + myvarnames: "{{ q('varnames', '^my') }}" + mydict: "{{ dict(myvarnames | zip(q('vars', *myvarnames))) }}" + +A quick explanation, since there is a lot to unpack from these two lines: + + - The ``varnames`` lookup returns a list of variables that match "begin with ``my``". + - Then feeding the list from the previous step into the ``vars`` lookup to get the list of values. + The ``*`` is used to 'dereference the list' (a pythonism that works in Jinja), otherwise it would take the list as a single argument. + - Both lists get passed to the ``zip`` filter to pair them off into a unified list (key, value, key2, value2, ...). + - The dict function then takes this 'list of pairs' to create the dictionary. + + +An example on how to use facts to find a host's data that meets condition X: + + +.. code-block:: YAML+Jinja + + vars: + uptime_of_host_most_recently_rebooted: "{{ansible_play_hosts_all | map('extract', hostvars, 'ansible_uptime_seconds') | sort | first}}" + + +Using an example from @zoradache on reddit, to show the 'uptime in days/hours/minutes' (assumes facts where gathered). +https://www.reddit.com/r/ansible/comments/gj5a93/trying_to_get_uptime_from_seconds/fqj2qr3/ + +.. code-block:: YAML+Jinja + + - debug: + msg: Timedelta {{ now() - now().fromtimestamp(now(fmt='%s') | int - ansible_uptime_seconds) }} + + +.. seealso:: + + :doc:`playbooks_filters` + Jinja2 filters included with Ansible + :doc:`playbooks_tests` + Jinja2 tests included with Ansible + `Jinja2 Docs `_ + Jinja2 documentation, includes lists for core filters and tests diff --git a/docs/docsite/rst/user_guide/intro_getting_started.rst b/docs/docsite/rst/user_guide/intro_getting_started.rst index 6379f5c5b9e9b0..58ab7fe6c355c0 100644 --- a/docs/docsite/rst/user_guide/intro_getting_started.rst +++ b/docs/docsite/rst/user_guide/intro_getting_started.rst @@ -109,6 +109,14 @@ You can read more about privilege escalation in :ref:`become`. Congratulations! You have contacted your nodes using Ansible. You used a basic inventory file and an ad-hoc command to direct Ansible to connect to specific remote nodes, copy a module file there and execute it, and return output. You have a fully working infrastructure. +Resources +================================= +- `Product Demos `_ +- `Katakoda `_ +- `Workshops `_ +- `Ansible Examples `_ +- `Ansible Baseline `_ + Next steps ========== Next you can read about more real-world cases in :ref:`intro_adhoc`, diff --git a/docs/docsite/rst/user_guide/playbooks_advanced_syntax.rst b/docs/docsite/rst/user_guide/playbooks_advanced_syntax.rst index 8ab71aa87b5888..2edf36d39d6e69 100644 --- a/docs/docsite/rst/user_guide/playbooks_advanced_syntax.rst +++ b/docs/docsite/rst/user_guide/playbooks_advanced_syntax.rst @@ -104,6 +104,8 @@ You've anchored the value of ``version`` with the ``&my_version`` anchor, and re :ref:`playbooks_variables` All about variables + :doc:`complex_data_manipulation` + Doing complex data manipulation in Ansible `User Mailing List `_ Have a question? Stop by the google group! `irc.freenode.net `_ diff --git a/docs/docsite/rst/user_guide/playbooks_filters.rst b/docs/docsite/rst/user_guide/playbooks_filters.rst index 87cf00d5d9d9e6..1487b295796dba 100644 --- a/docs/docsite/rst/user_guide/playbooks_filters.rst +++ b/docs/docsite/rst/user_guide/playbooks_filters.rst @@ -146,7 +146,7 @@ Transforming lists into dictionaries .. versionadded:: 2.7 -Use the ``items2dict``filter to transform a list into a dictionary, mapping the content into ``key: value`` pairs:: +Use the ``items2dict`` filter to transform a list into a dictionary, mapping the content into ``key: value`` pairs:: {{ tags | items2dict }} @@ -1532,7 +1532,7 @@ To get the root and extension of a path or file name (new in version 2.0):: The ``splitext`` filter returns a string. The individual components can be accessed by using the ``first`` and ``last`` filters:: # with path == 'nginx.conf' the return would be 'nginx' - {{ path | splitext | first }} + {{ path | splitext | first }} # with path == 'nginx.conf' the return would be 'conf' {{ path | splitext | last }} diff --git a/docs/docsite/rst/user_guide/playbooks_reuse_roles.rst b/docs/docsite/rst/user_guide/playbooks_reuse_roles.rst index 8c1e4d8ba5cd2e..3eea2e94197437 100644 --- a/docs/docsite/rst/user_guide/playbooks_reuse_roles.rst +++ b/docs/docsite/rst/user_guide/playbooks_reuse_roles.rst @@ -130,7 +130,7 @@ When you use the ``roles`` option at the play level, Ansible treats the roles as - Any ``pre_tasks`` defined in the play. - Any handlers triggered by pre_tasks. -- Each role listed in ``roles:``, in the order listed. Any role dependencies defined in the roles ``meta/main.yml`` run first, subject to tag filtering and conditionals. See :ref:`role_dependencies` for more details. +- Each role listed in ``roles:``, in the order listed. Any role dependencies defined in the role's ``meta/main.yml`` run first, subject to tag filtering and conditionals. See :ref:`role_dependencies` for more details. - Any ``tasks`` defined in the play. - Any handlers triggered by the roles or tasks. - Any ``post_tasks`` defined in the play. diff --git a/docs/docsite/rst/user_guide/playbooks_special_topics.rst b/docs/docsite/rst/user_guide/playbooks_special_topics.rst index a1646413d7d264..0ef1f53086ee14 100644 --- a/docs/docsite/rst/user_guide/playbooks_special_topics.rst +++ b/docs/docsite/rst/user_guide/playbooks_special_topics.rst @@ -16,6 +16,7 @@ As you write more playbooks and roles, you might have some special use cases. Fo playbooks_environment playbooks_error_handling playbooks_advanced_syntax + complex_data_manipulation ../plugins/plugins playbooks_prompts playbooks_tags diff --git a/lib/ansible/plugins/inventory/toml.py b/lib/ansible/plugins/inventory/toml.py index efbec3721645a2..32885956830868 100644 --- a/lib/ansible/plugins/inventory/toml.py +++ b/lib/ansible/plugins/inventory/toml.py @@ -4,7 +4,7 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -DOCUMENTATION = ''' +DOCUMENTATION = r''' inventory: toml version_added: "2.8" short_description: Uses a specific TOML file as an inventory source. @@ -15,7 +15,8 @@ - Requires the 'toml' python library ''' -EXAMPLES = ''' +EXAMPLES = r''' +# Following are examples of 3 different inventories in TOML format example1: | [all.vars] has_java = false