Docs backportapalooza 4 (#70875)

* Pipe lookup plugin usage example documentation fix (#70679)

(cherry picked from commit 58d24584c0)

* Fix misleading documentation for naming blocks (#68458)

From what I have observed it is the block itself that doesn't support the name attribute rather than the tasks inside the block.

* Update docs/docsite/rst/user_guide/playbooks_blocks.rst

Co-authored-by: Alicia Cozine <879121+acozine@users.noreply.github.com>
(cherry picked from commit 633c2d0522)

* Fix incorrect statement to set a variable for a playbook (#70712)

Fixes #70638

(cherry picked from commit 59513ae673)

* Make Sources, Plugins sections easier to read (#70652)

Re-wrote the Inventory Sources section and also the next section to have shorter, clearer sentences with a more active voice.

(cherry picked from commit fb3db170cc)

* fix rstcheck problem and gitignore collections dir (#70764)

(cherry picked from commit 24e5d3a51c)

* add note for write permission on rst files (#70766)

* add note for write permission on rst files
* Update docs/docsite/rst/community/documentation_contributions.rst

Co-authored-by: Toshio Kuratomi <a.badger@gmail.com>
(cherry picked from commit 2a7df5e07b)

* Modification of 'Adding modules and plugins locally' topic (#70659)

* Remediated the topic to comply with IBM style guide and minimalism practices
Co-authored-by: Alicia Cozine <879121+acozine@users.noreply.github.com>

(cherry picked from commit 1733253297)

* WIP: add collections as an intersphinx link (#70826)

* adds collections as a ref for intersphinx

* no need for intersphinx

Co-authored-by: Alicia Cozine <acozine@users.noreply.github.com>
(cherry picked from commit b28d59124b)

* Proper example for splitext filter in docs (#70494)

* Update playbooks_filters.rst with a clear example of how to extract its 2 tokens.

Co-authored-by: Sloane Hertel <shertel@redhat.com>
(cherry picked from commit 7a42d27462)

* Few fixes for reference_appendices/faq.html (#70719)

* Format using `` instead of `, add line breaks for long lines, rephrase or remove useless text.
Move some text.

* Add clearer version of OpenSSh is affected by SCP bug

* Review some pages using ansible doc writing guide.

(cherry picked from commit 92e16c2838)

Co-authored-by: Roman Gorshunov <34521622+gorshunovr@users.noreply.github.com>
Co-authored-by: David Rieger <david@isan.engineer>
Co-authored-by: Baptiste Mille-Mathias <baptiste.millemathias@gmail.com>
Co-authored-by: Stef B <regendo@users.noreply.github.com>
Co-authored-by: Sayee <57951841+sayee-jadhav@users.noreply.github.com>
Co-authored-by: Alicia Cozine <879121+acozine@users.noreply.github.com>
Co-authored-by: Fixmetal <fixmetal@gmail.com>
pull/70967/head
Sandra McCann 4 years ago committed by GitHub
parent 12784beb87
commit 8d2b25d490
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,4 +14,6 @@ objects.inv
rst/dev_guide/testing/sanity/index.rst rst/dev_guide/testing/sanity/index.rst
rst/modules/*.rst rst/modules/*.rst
rst/playbooks_keywords.rst rst/playbooks_keywords.rst
rst/collections/
*.min.css *.min.css

@ -102,6 +102,10 @@ You can drop ``--user`` if you have set up a virtual environment (venv/virtenv).
On macOS with Xcode, you may need to install ``six`` and ``pyparsing`` with ``--ignore-installed`` to get versions that work with ``sphinx``. On macOS with Xcode, you may need to install ``six`` and ``pyparsing`` with ``--ignore-installed`` to get versions that work with ``sphinx``.
.. note::
After checking out ``ansible/ansible``, make sure the ``docs/docsite/rst`` directory has strict enough permissions. It should only be writable by the owner's account. If your default ``umask`` is not 022, you can use ``chmod go-w docs/docsite/rst`` to set the permissions correctly in your new branch. Optionally, you can set your ``umask`` to 022 to make all newly created files on your system (including those created by ``git clone``) have the correct permissions.
.. _testing_documentation_locally: .. _testing_documentation_locally:
Testing the documentation locally Testing the documentation locally

@ -277,10 +277,6 @@ autoclass_content = 'both'
intersphinx_mapping = {'python': ('https://docs.python.org/2/', (None, '../python2.inv')), intersphinx_mapping = {'python': ('https://docs.python.org/2/', (None, '../python2.inv')),
'python3': ('https://docs.python.org/3/', (None, '../python3.inv')), 'python3': ('https://docs.python.org/3/', (None, '../python3.inv')),
'jinja2': ('http://jinja.palletsprojects.com/', (None, '../jinja2.inv')), 'jinja2': ('http://jinja.palletsprojects.com/', (None, '../jinja2.inv')),
'collections': ('https://docs.ansible.com/collections/',
(None, '../collections.inv',
'http://docs.testing.ansible.com/collections/objects.inv',
'../_collections_build/html/objects.inv')),
'ansible_2_9': ('https://docs.ansible.com/ansible/2.9/', (None, '../ansible_2_9.inv')), 'ansible_2_9': ('https://docs.ansible.com/ansible/2.9/', (None, '../ansible_2_9.inv')),
'ansible_2_8': ('https://docs.ansible.com/ansible/2.8/', (None, '../ansible_2_8.inv')), 'ansible_2_8': ('https://docs.ansible.com/ansible/2.8/', (None, '../ansible_2_8.inv')),
'ansible_2_7': ('https://docs.ansible.com/ansible/2.7/', (None, '../ansible_2_7.inv')), 'ansible_2_7': ('https://docs.ansible.com/ansible/2.7/', (None, '../ansible_2_7.inv')),

@ -279,7 +279,7 @@ This creates a tarball of the built collection in the current directory which ca
└── ... └── ...
.. note:: .. note::
* Certain files and folders are excluded when building the collection artifact. See :ref:`ignoring_files_and_folders_collections` to exclude other files you would not wish to distribute. * Certain files and folders are excluded when building the collection artifact. See :ref:`ignoring_files_and_folders_collections` to exclude other files you would not want to distribute.
* If you used the now-deprecated ``Mazer`` tool for any of your collections, delete any and all files it added to your :file:`releases/` directory before you build your collection with ``ansible-galaxy``. * If you used the now-deprecated ``Mazer`` tool for any of your collections, delete any and all files it added to your :file:`releases/` directory before you build your collection with ``ansible-galaxy``.
* The current Galaxy maximum tarball size is 2 MB. * The current Galaxy maximum tarball size is 2 MB.
@ -430,7 +430,7 @@ To upload the collection artifact with the ``ansible-galaxy`` command:
The above command assumes you have retrieved and stored your API token as part of a Galaxy server list. See :ref:`galaxy_get_token` for details. The above command assumes you have retrieved and stored your API token as part of a Galaxy server list. See :ref:`galaxy_get_token` for details.
The ``ansible-galaxy collection publish`` command triggers an import process, just as if you uploaded the collection through the Galaxy website. The ``ansible-galaxy collection publish`` command triggers an import process, just as if you uploaded the collection through the Galaxy website.
The command waits until the import process completes before reporting the status back. If you wish to continue The command waits until the import process completes before reporting the status back. If you want to continue
without waiting for the import result, use the ``--no-wait`` argument and manually look at the import progress in your without waiting for the import result, use the ``--no-wait`` argument and manually look at the import progress in your
`My Imports <https://galaxy.ansible.com/my-imports/>`_ page. `My Imports <https://galaxy.ansible.com/my-imports/>`_ page.

@ -14,9 +14,9 @@ If the source you want is not currently covered by existing plugins, you can cre
In previous versions you had to create a script or program that can output JSON in the correct format when invoked with the proper arguments. In previous versions you had to create a script or program that can output JSON in the correct format when invoked with the proper arguments.
You can still use and write inventory scripts, as we ensured backwards compatibility via the :ref:`script inventory plugin <script_inventory>` You can still use and write inventory scripts, as we ensured backwards compatibility via the :ref:`script inventory plugin <script_inventory>`
and there is no restriction on the programming language used. and there is no restriction on the programming language used.
If you choose to write a script, however, you will need to implement some features yourself. If you choose to write a script, however, you will need to implement some features yourself
i.e caching, configuration management, dynamic variable and group composition, etc. such as caching, configuration management, dynamic variable and group composition, and other features.
While with :ref:`inventory plugins <inventory_plugins>` you can leverage the Ansible codebase to add these common features. If you use :ref:`inventory plugins <inventory_plugins>` instead, you can leverage the Ansible codebase to add these common features.
.. _inventory_sources: .. _inventory_sources:
@ -24,25 +24,26 @@ While with :ref:`inventory plugins <inventory_plugins>` you can leverage the Ans
Inventory sources Inventory sources
================= =================
Inventory sources are strings (i.e what you pass to ``-i`` in the command line), Inventory sources are the input strings that inventory plugins work with.
they can represent a path to a file/script or just be the raw data for the plugin to use. An inventory source can be a path to a file or to a script, or it can be raw data that the plugin can interpret.
Here are some plugins and the type of source they use:
The table below shows some examples of inventory plugins and the kinds of source you can pass to them with ``-i`` on the command line.
+--------------------------------------------+---------------------------------------+
| Plugin | Source | +--------------------------------------------+-----------------------------------------+
+--------------------------------------------+---------------------------------------+ | Plugin | Source |
| :ref:`host list <host_list_inventory>` | A comma separated list of hosts | +--------------------------------------------+-----------------------------------------+
+--------------------------------------------+---------------------------------------+ | :ref:`host list <host_list_inventory>` | A comma-separated list of hosts |
| :ref:`yaml <yaml_inventory>` | Path to a YAML format data file | +--------------------------------------------+-----------------------------------------+
+--------------------------------------------+---------------------------------------+ | :ref:`yaml <yaml_inventory>` | Path to a YAML format data file |
| :ref:`constructed <constructed_inventory>` | Path to a YAML configuration file | +--------------------------------------------+-----------------------------------------+
+--------------------------------------------+---------------------------------------+ | :ref:`constructed <constructed_inventory>` | Path to a YAML configuration file |
| :ref:`ini <ini_inventory>` | Path to an INI formatted data file | +--------------------------------------------+-----------------------------------------+
+--------------------------------------------+---------------------------------------+ | :ref:`ini <ini_inventory>` | Path to an INI formatted data file |
| :ref:`virtualbox <virtualbox_inventory>` | Path to a YAML configuration file | +--------------------------------------------+-----------------------------------------+
+--------------------------------------------+---------------------------------------+ | :ref:`virtualbox <virtualbox_inventory>` | Path to a YAML configuration file |
| :ref:`script plugin <script_inventory>` | Path to an executable outputting JSON | +--------------------------------------------+-----------------------------------------+
+--------------------------------------------+---------------------------------------+ | :ref:`script plugin <script_inventory>` | Path to an executable that outputs JSON |
+--------------------------------------------+-----------------------------------------+
.. _developing_inventory_inventory_plugins: .. _developing_inventory_inventory_plugins:
@ -50,14 +51,14 @@ Here are some plugins and the type of source they use:
Inventory plugins Inventory plugins
================= =================
Like most plugin types (except modules) they must be developed in Python, since they execute on the controller they should match the same requirements :ref:`control_node_requirements`. Like most plugin types (except modules), inventory plugins must be developed in Python. They execute on the controller and should therefore match the :ref:`control_node_requirements`.
Most of the documentation in :ref:`developing_plugins` also applies here, so as to not repeat ourselves, you should read that document first and we'll include inventory plugin specifics next. Most of the documentation in :ref:`developing_plugins` also applies here. You should read that document first for a general understanding and then come back to this document for specifics on inventory plugins.
Inventory plugins normally only execute at the start of a run, before playbooks/plays and roles are loaded, Inventory plugins normally only execute at the start of a run, before playbooks, plays, and roles are loaded.
but they can be 're-executed' via the ``meta: refresh_inventory`` task, which will clear out the existing inventory and rebuild it. However, you can use the ``meta: refresh_inventory`` task to clear the current inventory and to execute the inventory plugins again, which will generate a new inventory.
When using the 'persistent' cache, inventory plugins can also use the configured cache plugin to store and retrieve data to avoid costly external calls. If you use the persistent cache, inventory plugins can also use the configured cache plugin to store and retrieve data. This avoids repeating costly external calls.
.. _developing_an_inventory_plugin: .. _developing_an_inventory_plugin:

@ -5,12 +5,11 @@
Adding modules and plugins locally Adding modules and plugins locally
********************************** **********************************
.. contents:: The easiest, quickest, and the most popular way to extend Ansible is to use a local module or a plugin. You can create them or copy existing ones for local use. You can store a local module or plugin on your Ansible control node and share it with your team or organization. You can also share a local plugin or module by embedding it in a role and publishing it on Ansible Galaxy. If you are using roles on Ansible Galaxy, then you are already using local modules and plugins without realizing it.
:local:
The easiest, quickest, and most popular way to extend Ansible is to copy or write a module or a plugin for local use. You can store local modules and plugins on your Ansible control node for use within your team or organization. You can also share a local plugin or module by embedding it in a role and publishing it on Ansible Galaxy. If you've been using roles off Galaxy, you may have been using local modules and plugins without even realizing it. If you're using a local module or plugin that already exists, this page is all you need. If you are using an existing module or plugin but Ansible can't find it, this page is all you need. However, if you want to create a plugin or a module, go to :ref:`developing_plugins` and :ref:`developing_modules_general` topics and then return to this page to know how to add it locally.
Extending Ansible with local modules and plugins offers lots of shortcuts: Extending Ansible with local modules and plugins offers lots of shortcuts such as:
* You can copy other people's modules and plugins. * You can copy other people's modules and plugins.
* If you're writing a new module, you can choose any programming language you like. * If you're writing a new module, you can choose any programming language you like.
@ -18,28 +17,35 @@ Extending Ansible with local modules and plugins offers lots of shortcuts:
* You don't have to open a pull request. * You don't have to open a pull request.
* You don't have to add tests (though we recommend that you do!). * You don't have to add tests (though we recommend that you do!).
To save a local module or plugin so Ansible can find and use it, drop the module or plugin in the correct "magic" directory. For local modules, use the name of the file as the module name: for example, if the module file is ``~/.ansible/plugins/modules/local_users.py``, use ``local_users`` as the module name. To save a local module or plugin such that Ansible can find and use it, add the module or plugin in the appropriate directory (the directories are specified in later parts of this topic).
.. contents::
:local:
.. _modules_vs_plugins: .. _modules_vs_plugins:
Modules and plugins: what's the difference? Modules and plugins: what's the difference?
=========================================== ===========================================
If you're looking to add local functionality to Ansible, you may be wondering whether you need a module or a plugin. Here's a quick overview of the differences: If you're looking to add local functionality to Ansible, you might wonder whether you need a module or a plugin. Here's a quick overview to help you decide between the two:
* Modules are reusable, standalone scripts that can be used by the Ansible API, the :command:`ansible` command, or the :command:`ansible-playbook` command. Modules provide a defined interface, accepting arguments and returning information to Ansible by printing a JSON string to stdout before exiting. Modules execute on the target system (usually that means on a remote system) in separate processes. * Modules are reusable, standalone scripts that can be used by the Ansible API, the :command:`ansible` command, or the :command:`ansible-playbook` command. Modules provide a defined interface. Each module accepts arguments and returns information to Ansible by printing a JSON string to stdout before exiting. Modules execute on the target system (usually that means on a remote system) in separate processes.
* :ref:`Plugins <plugins_lookup>` augment Ansible's core functionality and execute on the control node within the ``/usr/bin/ansible`` process. Plugins offer options and extensions for the core features of Ansible - transforming data, logging output, connecting to inventory, and more. * :ref:`Plugins <plugins_lookup>` augment Ansible's core functionality and execute on the control node within the ``/usr/bin/ansible`` process. Plugins offer options and extensions for the core features of Ansible - transforming data, logging output, connecting to inventory, and more.
.. _local_modules: .. _local_modules:
Adding a module locally Adding a module locally
======================= =======================
Ansible automatically loads all executable files found in certain directories as modules, so you can create or add a local module in any of these locations: Ansible automatically loads all executable files found in certain directories as modules.
For local modules, use the name of the file as the module name: for example, if the module file is ``~/.ansible/plugins/modules/local_users.py``, use ``local_users`` as the module name.
To load your local modules automatically and make them available to all playbooks and roles, add them in any of these locations:
* any directory added to the ``ANSIBLE_LIBRARY`` environment variable (``$ANSIBLE_LIBRARY`` takes a colon-separated list like ``$PATH``) * any directory added to the ``ANSIBLE_LIBRARY`` environment variable (``$ANSIBLE_LIBRARY`` takes a colon-separated list like ``$PATH``)
* ``~/.ansible/plugins/modules/`` * ``~/.ansible/plugins/modules/``
* ``/usr/share/ansible/plugins/modules/`` * ``/usr/share/ansible/plugins/modules/``
Once you save your module file in one of these locations, Ansible will load it and you can use it in any local task, playbook, or role. After you save your module file in one of these locations, Ansible loads it and you can use it in any local task, playbook, or role.
To confirm that ``my_custom_module`` is available: To confirm that ``my_custom_module`` is available:
@ -51,22 +57,19 @@ or
.. note:: .. note::
Currently, ``ansible-doc`` command can only parse Python modules for the module documentation. If you have module written in a different programming language other than Python, please write a documentation in Python file adjacent to module file. Currently, the ``ansible-doc`` command can parse module documentation only from modules written in Python. If you have a module written in a programming language other than Python, please write the documentation in a Python file adjacent to the module file.
To use a local module only in certain playbooks:
* store it in a sub-directory called ``library`` in the directory that contains the playbook(s) You can limit the availability of your local module. If you want to use a local module only with selected playbooks or only with a single role, load it in one of the following locations:
To use a local module only in a single role: * In a selected playbook or playbooks: Store the module in a subdirectory called ``library`` in the directory that contains those playbooks.
* In a single role: Store the module in a subdirectory called ``library`` within that role.
* store it in a sub-directory called ``library`` within that role
.. _distributing_plugins: .. _distributing_plugins:
.. _local_plugins: .. _local_plugins:
Adding a plugin locally Adding a plugin locally
======================= =======================
Ansible loads plugins automatically too, loading each type of plugin separately from a directory named for the type of plugin. Here's the full list of plugin directory names: Ansible loads plugins automatically too, and loads each type of plugin separately from a directory named for the type of plugin. Here's the full list of plugin directory names:
* action_plugins* * action_plugins*
* cache_plugins * cache_plugins
@ -80,24 +83,23 @@ Ansible loads plugins automatically too, loading each type of plugin separately
* test_plugins* * test_plugins*
* vars_plugins * vars_plugins
To load your local plugins automatically, create or add them in any of these locations: .. note::
After you add the plugins and verify that they are available for use, you can see the documentation for all the plugins except for the ones marked with an asterisk (*) above.
To load your local plugins automatically, add them in any of these locations:
* any directory added to the relevant ``ANSIBLE_plugin_type_PLUGINS`` environment variable (these variables, such as ``$ANSIBLE_INVENTORY_PLUGINS`` and ``$ANSIBLE_VARS_PLUGINS`` take colon-separated lists like ``$PATH``) * any directory added to the relevant ``ANSIBLE_plugin_type_PLUGINS`` environment variable (these variables, such as ``$ANSIBLE_INVENTORY_PLUGINS`` and ``$ANSIBLE_VARS_PLUGINS`` take colon-separated lists like ``$PATH``)
* the directory named for the correct ``plugin_type`` within ``~/.ansible/plugins/`` - for example, ``~/.ansible/plugins/callback`` * the directory named for the correct ``plugin_type`` within ``~/.ansible/plugins/`` - for example, ``~/.ansible/plugins/callback``
* the directory named for the correct ``plugin_type`` within ``/usr/share/ansible/plugins/`` - for example, ``/usr/share/ansible/plugins/action`` * the directory named for the correct ``plugin_type`` within ``/usr/share/ansible/plugins/`` - for example, ``/usr/share/ansible/plugins/action``
Once your plugin file is in one of these locations, Ansible will load it and you can use it in a any local module, task, playbook, or role. Alternatively, you can edit your ``ansible.cfg`` file to add directories that contain local plugins - see :ref:`ansible_configuration_settings` for details. After your plugin file is in one of these locations, Ansible loads it and you can use it in any local module, task, playbook, or role. Alternatively, you can edit your ``ansible.cfg`` file to add directories that contain local plugins. For details about adding directories of local plugins, see :ref:`ansible_configuration_settings`.
To confirm that ``plugins/plugin_type/my_custom_plugin`` is available: To confirm that ``plugins/plugin_type/my_custom_plugin`` is available:
* type ``ansible-doc -t <plugin_type> my_custom_lookup_plugin``. For example, ``ansible-doc -t lookup my_custom_lookup_plugin``. You should see the documentation for that plugin. This works for all plugin types except the ones marked with ``*`` in the list above - see :ref:`ansible-doc` for more details. * type ``ansible-doc -t <plugin_type> my_custom_lookup_plugin``. For example, ``ansible-doc -t lookup my_custom_lookup_plugin``. You should see the documentation for that plugin. This works for all plugin types except the ones marked with ``*`` in the list above - see :ref:`ansible-doc` for more details.
To use your local plugin only in certain playbooks: You can limit the availability of your local plugin. If you want to use a local plugin only with selected playbooks or only with a single role, load it in one of the following locations:
* store it in a sub-directory for the correct ``plugin_type`` (for example, ``callback_plugins`` or ``inventory_plugins``) in the directory that contains the playbook(s)
To use your local plugin only in a single role:
* store it in a sub-directory for the correct ``plugin_type`` (for example, ``cache_plugins`` or ``strategy_plugins``) within that role
When shipped as part of a role, the plugin will be available as soon as the role is called in the play. * In a selected playbook or playbooks: Store the plugin in a subdirectory for the correct ``plugin_type`` (for example, ``callback_plugins`` or ``inventory_plugins``) in the directory that contains the playbooks.
* In a single role: Store the plugin in a subdirectory for the correct ``plugin_type`` (for example, ``cache_plugins`` or ``strategy_plugins``) within that role. When shipped as part of a role, the plugin is available as soon as the role is executed.

@ -628,7 +628,7 @@ tests for win_stat:
- Create a copy of ``./test/integration/inventory.winrm.template`` and name it ``inventory.winrm``. - Create a copy of ``./test/integration/inventory.winrm.template`` and name it ``inventory.winrm``.
- Fill in entries under ``[windows]`` and set the required variables that are needed to connect to the host. - Fill in entries under ``[windows]`` and set the required variables that are needed to connect to the host.
- :ref:`Install the required Python modules <windows_winrm>` to support WinRM and a configured authentication method. - :ref:`Install the required Python modules <windows_winrm>` to support WinRM and a configured authentication method.
- To execute the integration tests, run ``ansible-test windows-integration win_stat``; you can replace ``win_stat`` with the role you wish to test. - To execute the integration tests, run ``ansible-test windows-integration win_stat``; you can replace ``win_stat`` with the role you want to test.
This will execute all the tests currently defined for that role. You can set This will execute all the tests currently defined for that role. You can set
the verbosity level using the ``-v`` argument just as you would with the verbosity level using the ``-v`` argument just as you would with

@ -120,7 +120,7 @@ When you choose to use your username and password, your password is not sent to
It then sends the token to Galaxy, which in turn verifies that your identity and returns a Galaxy access token. After authentication completes the GitHub token is It then sends the token to Galaxy, which in turn verifies that your identity and returns a Galaxy access token. After authentication completes the GitHub token is
destroyed. destroyed.
If you do not wish to use your GitHub password, or if you have two-factor authentication enabled with GitHub, use the ``--github-token`` option to pass a personal access token that you create. If you do not want to use your GitHub password, or if you have two-factor authentication enabled with GitHub, use the ``--github-token`` option to pass a personal access token that you create.
Import a role Import a role

@ -173,9 +173,9 @@ Installing roles from Galaxy
The ``ansible-galaxy`` command comes bundled with Ansible, and you can use it to install roles from Galaxy or directly from a git based SCM. You can The ``ansible-galaxy`` command comes bundled with Ansible, and you can use it to install roles from Galaxy or directly from a git based SCM. You can
also use it to create a new role, remove roles, or perform tasks on the Galaxy website. also use it to create a new role, remove roles, or perform tasks on the Galaxy website.
The command line tool by default communicates with the Galaxy website API using the server address *https://galaxy.ansible.com*. Since the `Galaxy project <https://github.com/ansible/galaxy>`_ The command line tool by default communicates with the Galaxy website API using the server address *https://galaxy.ansible.com*. If you run your own internal Galaxy server
is an open source project, you may be running your own internal Galaxy server and wish to override the default server address. You can do this using the *--server* option and want to use it instead of the default one, pass the ``--server`` option following the address of this galaxy server. You can set permanently this option by setting
or by setting the Galaxy server value in your *ansible.cfg* file. For information on setting the value in *ansible.cfg* see :ref:`galaxy_server`. the Galaxy server value in your ``ansible.cfg`` file to use it . For information on setting the value in *ansible.cfg* see :ref:`galaxy_server`.
Installing roles Installing roles
@ -195,8 +195,8 @@ By default, Ansible downloads roles to the first writable directory in the defau
You can override this with one of the following options: You can override this with one of the following options:
* Set the environment variable :envvar:`ANSIBLE_ROLES_PATH` in your session. * Set the environment variable :envvar:`ANSIBLE_ROLES_PATH` in your session.
* Define ``roles_path`` in an ``ansible.cfg`` file.
* Use the ``--roles-path`` option for the ``ansible-galaxy`` command. * Use the ``--roles-path`` option for the ``ansible-galaxy`` command.
* Define ``roles_path`` in an ``ansible.cfg`` file.
The following provides an example of using ``--roles-path`` to install the role into the current working directory: The following provides an example of using ``--roles-path`` to install the role into the current working directory:
@ -212,7 +212,8 @@ The following provides an example of using ``--roles-path`` to install the role
Installing a specific version of a role Installing a specific version of a role
--------------------------------------- ---------------------------------------
When the Galaxy server imports a role, it imports any git tags matching the Semantic Version format as versions. In turn, you can download a specific version of a role by specifying one of the imported tags. When the Galaxy server imports a role, it imports any git tags matching the `Semantic Version <https://semver.org/>`_ format as versions.
In turn, you can download a specific version of a role by specifying one of the imported tags.
To see the available versions for a role: To see the available versions for a role:

@ -8,16 +8,26 @@ Here are some commonly asked questions and their answers.
.. _set_environment: .. _set_environment:
How can I set the PATH or any other environment variable for a task or entire playbook? How can I set the PATH or any other environment variable for a task or entire play?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Setting environment variables can be done with the `environment` keyword. It can be used at the task or other levels in the play:: Setting environment variables can be done with the `environment` keyword. It can be used at the task or other levels in the play.
.. code-block:: yaml
shell:
cmd: date
environment:
LANG=fr_FR.UTF-8
.. code-block:: yaml
hosts: servers
environment: environment:
PATH: "{{ ansible_env.PATH }}:/thingy/bin" PATH: "{{ ansible_env.PATH }}:/thingy/bin"
SOME: value SOME: value
.. note:: starting in 2.0.1 the setup task from gather_facts also inherits the environment directive from the play, you might need to use the `|default` filter to avoid errors if setting this at play level. .. note:: starting in 2.0.1 the setup task from ``gather_facts`` also inherits the environment directive from the play, you might need to use the ``|default`` filter to avoid errors if setting this at play level.
.. _faq_setting_users_and_ports: .. _faq_setting_users_and_ports:
@ -51,25 +61,24 @@ See the rest of the documentation for more information about how to organize var
How do I get ansible to reuse connections, enable Kerberized SSH, or have Ansible pay attention to my local SSH config file? How do I get ansible to reuse connections, enable Kerberized SSH, or have Ansible pay attention to my local SSH config file?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Switch your default connection type in the configuration file to 'ssh', or use '-c ssh' to use Switch your default connection type in the configuration file to ``ssh``, or use ``-c ssh`` to use
Native OpenSSH for connections instead of the python paramiko library. In Ansible 1.2.1 and later, 'ssh' will be used Native OpenSSH for connections instead of the python paramiko library. In Ansible 1.2.1 and later, ``ssh`` will be used
by default if OpenSSH is new enough to support ControlPersist as an option. by default if OpenSSH is new enough to support ControlPersist as an option.
Paramiko is great for starting out, but the OpenSSH type offers many advanced options. You will want to run Ansible Paramiko is great for starting out, but the OpenSSH type offers many advanced options. You will want to run Ansible
from a machine new enough to support ControlPersist, if you are using this connection type. You can still manage from a machine new enough to support ControlPersist, if you are using this connection type. You can still manage
older clients. If you are using RHEL 6, CentOS 6, SLES 10 or SLES 11 the version of OpenSSH is still a bit old, so older clients. If you are using RHEL 6, CentOS 6, SLES 10 or SLES 11 the version of OpenSSH is still a bit old, so
consider managing from a Fedora or openSUSE client even though you are managing older nodes, or just use paramiko. consider managing from a Fedora or openSUSE client even though you are managing older nodes, or just use paramiko.
We keep paramiko as the default as if you are first installing Ansible on an EL box, it offers a better experience We keep paramiko as the default as if you are first installing Ansible on these enterprise operating systems, it offers a better experience for new users.
for new users.
.. _use_ssh_jump_hosts: .. _use_ssh_jump_hosts:
How do I configure a jump host to access servers that I have no direct access to? How do I configure a jump host to access servers that I have no direct access to?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
You can set a `ProxyCommand` in the You can set a ``ProxyCommand`` in the
`ansible_ssh_common_args` inventory variable. Any arguments specified in ``ansible_ssh_common_args`` inventory variable. Any arguments specified in
this variable are added to the sftp/scp/ssh command line when connecting this variable are added to the sftp/scp/ssh command line when connecting
to the relevant host(s). Consider the following inventory group: to the relevant host(s). Consider the following inventory group:
@ -84,32 +93,35 @@ You can create `group_vars/gatewayed.yml` with the following contents::
ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q user@gateway.example.com"' ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q user@gateway.example.com"'
Ansible will append these arguments to the command line when trying to Ansible will append these arguments to the command line when trying to
connect to any hosts in the group `gatewayed`. (These arguments are used connect to any hosts in the group ``gatewayed``. (These arguments are used
in addition to any `ssh_args` from `ansible.cfg`, so you do not need to in addition to any ``ssh_args`` from ``ansible.cfg``, so you do not need to
repeat global `ControlPersist` settings in `ansible_ssh_common_args`.) repeat global ``ControlPersist`` settings in ``ansible_ssh_common_args``.)
Note that `ssh -W` is available only with OpenSSH 5.4 or later. With Note that ``ssh -W`` is available only with OpenSSH 5.4 or later. With
older versions, it's necessary to execute `nc %h:%p` or some equivalent older versions, it's necessary to execute ``nc %h:%p`` or some equivalent
command on the bastion host. command on the bastion host.
With earlier versions of Ansible, it was necessary to configure a With earlier versions of Ansible, it was necessary to configure a
suitable `ProxyCommand` for one or more hosts in `~/.ssh/config`, suitable ``ProxyCommand`` for one or more hosts in ``~/.ssh/config``,
or globally by setting `ssh_args` in `ansible.cfg`. or globally by setting ``ssh_args`` in ``ansible.cfg``.
.. _ssh_serveraliveinterval: .. _ssh_serveraliveinterval:
How do I get Ansible to notice a dead target in a timely manner? How do I get Ansible to notice a dead target in a timely manner?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
You can add ``-o ServerAliveInterval=NumberOfSeconds`` in ``ssh_args`` from ``ansible.cfg``. Without this option, SSH and therefore Ansible will wait until the TCP connection times out. Another solution is to add ``ServerAliveInterval`` into your global SSH configuration. A good value for ``ServerAliveInterval`` is up to you to decide; keep in mind that ``ServerAliveCountMax=3`` is the SSH default so any value you set will be tripled before terminating the SSH session. You can add ``-o ServerAliveInterval=NumberOfSeconds`` in ``ssh_args`` from ``ansible.cfg``. Without this option,
SSH and therefore Ansible will wait until the TCP connection times out. Another solution is to add ``ServerAliveInterval``
into your global SSH configuration. A good value for ``ServerAliveInterval`` is up to you to decide; keep in mind that
``ServerAliveCountMax=3`` is the SSH default so any value you set will be tripled before terminating the SSH session.
.. _ec2_cloud_performance: .. _cloud_provider_performance:
How do I speed up management inside EC2? How do I speed up run of ansible for servers from cloud providers (EC2, openstack,.. )?
++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Don't try to manage a fleet of EC2 machines from your laptop. Connect to a management node inside EC2 first Don't try to manage a fleet of machines of a cloud provider from your laptop.
and run Ansible from there. Rather connect to a management node inside this cloud provider first and run Ansible from there.
.. _python_interpreters: .. _python_interpreters:
@ -136,12 +148,12 @@ workaround you can install Python 2 on the managed host and configure Ansible to
requires Python 2, you can also report a bug on our `bug tracker requires Python 2, you can also report a bug on our `bug tracker
<https://github.com/ansible/ansible/issues>`_ so that the incompatibility can be fixed in a future release. <https://github.com/ansible/ansible/issues>`_ so that the incompatibility can be fixed in a future release.
Do not replace the shebang lines of your python modules. Ansible will do this for you automatically at deploy time. Do not replace the shebang lines of your python modules. Ansible will do this for you automatically at deploy time.
Also, this works for ANY interpreter, i.e ruby: `ansible_ruby_interpreter`, perl: `ansible_perl_interpreter`, etc, Also, this works for ANY interpreter, i.e ruby: ``ansible_ruby_interpreter``, perl: ``ansible_perl_interpreter``, etc,
so you can use this for custom modules written in any scripting language and control the interpreter location. so you can use this for custom modules written in any scripting language and control the interpreter location.
Keep in mind that if you put `env` in your module shebang line (`#!/usr/bin/env <other>`), Keep in mind that if you put ``env`` in your module shebang line (``#!/usr/bin/env <other>``),
this facility will be ignored so you will be at the mercy of the remote `$PATH`. this facility will be ignored so you will be at the mercy of the remote `$PATH`.
.. _installation_faqs: .. _installation_faqs:
@ -153,7 +165,8 @@ While installing Ansible, sometimes you may encounter errors such as `No package
These errors are generally caused by the missing packages, which are dependencies of the packages required by Ansible. These errors are generally caused by the missing packages, which are dependencies of the packages required by Ansible.
For example, `libffi` package is dependency of `pynacl` and `paramiko` (Ansible -> paramiko -> pynacl -> libffi). For example, `libffi` package is dependency of `pynacl` and `paramiko` (Ansible -> paramiko -> pynacl -> libffi).
In order to solve these kinds of dependency issues, you might need to install required packages using the OS native package managers, such as `yum`, `dnf`, or `apt`, or as mentioned in the package installation guide. In order to solve these kinds of dependency issues, you might need to install required packages using
the OS native package managers, such as `yum`, `dnf`, or `apt`, or as mentioned in the package installation guide.
Refer to the documentation of the respective package for such dependencies and their installation methods. Refer to the documentation of the respective package for such dependencies and their installation methods.
@ -195,7 +208,7 @@ need to install them into the virtualenv. There are two methods:
$ virtualenv ansible --system-site-packages $ virtualenv ansible --system-site-packages
* Copy those files in manually from the system. For instance, for SELinux bindings you might do: * Copy those files in manually from the system. For instance, for SELinux bindings you might do:
.. code-block:: shell .. code-block:: shell
@ -217,8 +230,9 @@ By default, Solaris 10 and earlier run a non-POSIX shell which does not correctl
tmp directory Ansible uses ( :file:`~/.ansible/tmp`). If you see module failures on Solaris machines, this tmp directory Ansible uses ( :file:`~/.ansible/tmp`). If you see module failures on Solaris machines, this
is likely the problem. There are several workarounds: is likely the problem. There are several workarounds:
* You can set ``remote_tmp`` to a path that will expand correctly with the shell you are using (see the plugin documentation for :ref:`C shell<csh_shell>`, :ref:`fish shell<fish_shell>`, and :ref:`Powershell<powershell_shell>`). For * You can set ``remote_tmp`` to a path that will expand correctly with the shell you are using
example, in the ansible config file you can set:: (see the plugin documentation for :ref:`C shell<csh_shell>`, :ref:`fish shell<fish_shell>`,
and :ref:`Powershell<powershell_shell>`). For example, in the ansible config file you can set::
remote_tmp=$HOME/.ansible/tmp remote_tmp=$HOME/.ansible/tmp
@ -241,7 +255,7 @@ There are a few common errors that one might run into when trying to execute Ans
* Version 2.7.6 of python for z/OS will not work with Ansible because it represents strings internally as EBCDIC. * Version 2.7.6 of python for z/OS will not work with Ansible because it represents strings internally as EBCDIC.
To get around this limitation, download and install a later version of `python for z/OS <https://www.rocketsoftware.com/zos-open-source>`_ (2.7.13 or 3.6.1) that represents strings internally as ASCII. Version 2.7.13 is verified to work. To get around this limitation, download and install a later version of `python for z/OS <https://www.rocketsoftware.com/zos-open-source>`_ (2.7.13 or 3.6.1) that represents strings internally as ASCII. Version 2.7.13 is verified to work.
* When ``pipelining = False`` in `/etc/ansible/ansible.cfg` then Ansible modules are transferred in binary mode via sftp however execution of python fails with * When ``pipelining = False`` in `/etc/ansible/ansible.cfg` then Ansible modules are transferred in binary mode via sftp however execution of python fails with
@ -264,7 +278,7 @@ There are a few common errors that one might run into when trying to execute Ans
.. error:: .. error::
EE3501S The module libpython2.7.so was not found. EE3501S The module libpython2.7.so was not found.
On z/OS, you must execute python from gnu bash. If gnu bash is installed at ``/usr/lpp/bash``, you can fix this in your inventory by specifying an ``ansible_shell_executable``:: On z/OS, you must execute python from gnu bash. If gnu bash is installed at ``/usr/lpp/bash``, you can fix this in your inventory by specifying an ``ansible_shell_executable``::
zos1 ansible_shell_executable=/usr/lpp/bash/bin/bash zos1 ansible_shell_executable=/usr/lpp/bash/bin/bash
@ -274,7 +288,7 @@ There are a few common errors that one might run into when trying to execute Ans
What is the best way to make content reusable/redistributable? What is the best way to make content reusable/redistributable?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
If you have not done so already, read all about "Roles" in the playbooks documentation. This helps you make playbook content If you have not done so already, read all about "Roles" in the playbooks documentation. This helps you make playbook content
self-contained, and works well with things like git submodules for sharing content with others. self-contained, and works well with things like git submodules for sharing content with others.
If some of these plugin types look strange to you, see the API documentation for more details about ways Ansible can be extended. If some of these plugin types look strange to you, see the API documentation for more details about ways Ansible can be extended.
@ -292,8 +306,9 @@ See :ref:`intro_configuration`.
How do I disable cowsay? How do I disable cowsay?
++++++++++++++++++++++++ ++++++++++++++++++++++++
If cowsay is installed, Ansible takes it upon itself to make your day happier when running playbooks. If you decide If cowsay is installed, Ansible takes it upon itself to make your day happier when running playbooks. If you decide
that you would like to work in a professional cow-free environment, you can either uninstall cowsay, set ``nocows=1`` in ansible.cfg, or set the :envvar:`ANSIBLE_NOCOWS` environment variable: that you would like to work in a professional cow-free environment, you can either uninstall cowsay, set ``nocows=1``
in ``ansible.cfg``, or set the :envvar:`ANSIBLE_NOCOWS` environment variable:
.. code-block:: shell-session .. code-block:: shell-session
@ -304,13 +319,17 @@ that you would like to work in a professional cow-free environment, you can eith
How do I see a list of all of the ansible\_ variables? How do I see a list of all of the ansible\_ variables?
++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ansible by default gathers "facts" about the machines under management, and these facts can be accessed in Playbooks and in templates. To see a list of all of the facts that are available about a machine, you can run the "setup" module as an ad-hoc action: Ansible by default gathers "facts" about the machines under management, and these facts can be accessed in playbooks
and in templates. To see a list of all of the facts that are available about a machine, you can run the ``setup`` module
as an ad-hoc action:
.. code-block:: shell-session .. code-block:: shell-session
ansible -m setup hostname ansible -m setup hostname
This will print out a dictionary of all of the facts that are available for that particular host. You might want to pipe the output to a pager.This does NOT include inventory variables or internal 'magic' variables. See the next question if you need more than just 'facts'. This will print out a dictionary of all of the facts that are available for that particular host. You might want to pipe
the output to a pager.This does NOT include inventory variables or internal 'magic' variables. See the next question
if you need more than just 'facts'.
.. _browse_inventory_vars: .. _browse_inventory_vars:
@ -353,7 +372,8 @@ file with a list of servers. To do this, you can just access the "$groups" dicti
{{ host }} {{ host }}
{% endfor %} {% endfor %}
If you need to access facts about these hosts, for instance, the IP address of each hostname, you need to make sure that the facts have been populated. For example, make sure you have a play that talks to db_servers:: If you need to access facts about these hosts, for instance, the IP address of each hostname,
you need to make sure that the facts have been populated. For example, make sure you have a play that talks to db_servers::
- hosts: db_servers - hosts: db_servers
tasks: tasks:
@ -373,13 +393,13 @@ How do I access a variable name programmatically?
+++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++
An example may come up where we need to get the ipv4 address of an arbitrary interface, where the interface to be used may be supplied An example may come up where we need to get the ipv4 address of an arbitrary interface, where the interface to be used may be supplied
via a role parameter or other input. Variable names can be built by adding strings together, like so: via a role parameter or other input. Variable names can be built by adding strings together, like so:
.. code-block:: jinja .. code-block:: jinja
{{ hostvars[inventory_hostname]['ansible_' + which_interface]['ipv4']['address'] }} {{ hostvars[inventory_hostname]['ansible_' + which_interface]['ipv4']['address'] }}
The trick about going through hostvars is necessary because it's a dictionary of the entire namespace of variables. ``inventory_hostname`` The trick about going through hostvars is necessary because it's a dictionary of the entire namespace of variables. ``inventory_hostname``
is a magic variable that indicates the current host you are looping over in the host loop. is a magic variable that indicates the current host you are looping over in the host loop.
In the example above, if your interface names have dashes, you must replace them with underscores: In the example above, if your interface names have dashes, you must replace them with underscores:
@ -396,7 +416,8 @@ Also see dynamic_variables_.
How do I access a group variable? How do I access a group variable?
+++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++
Technically, you don't, Ansible does not really use groups directly. Groups are labels for host selection and a way to bulk assign variables, they are not a first class entity, Ansible only cares about Hosts and Tasks. Technically, you don't, Ansible does not really use groups directly. Groups are labels for host selection and a way to bulk assign variables,
they are not a first class entity, Ansible only cares about Hosts and Tasks.
That said, you could just access the variable by selecting a host that is part of that group, see first_host_in_a_group_ below for an example. That said, you could just access the variable by selecting a host that is part of that group, see first_host_in_a_group_ below for an example.
@ -406,9 +427,9 @@ That said, you could just access the variable by selecting a host that is part o
How do I access a variable of the first host in a group? How do I access a variable of the first host in a group?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
What happens if we want the ip address of the first webserver in the webservers group? Well, we can do that too. Note that if we What happens if we want the ip address of the first webserver in the webservers group? Well, we can do that too. Note that if we
are using dynamic inventory, which host is the 'first' may not be consistent, so you wouldn't want to do this unless your inventory are using dynamic inventory, which host is the 'first' may not be consistent, so you wouldn't want to do this unless your inventory
is static and predictable. (If you are using :ref:`ansible_tower`, it will use database order, so this isn't a problem even if you are using cloud is static and predictable. (If you are using :ref:`ansible_tower`, it will use database order, so this isn't a problem even if you are using cloud
based inventory scripts). based inventory scripts).
Anyway, here's the trick: Anyway, here's the trick:
@ -417,7 +438,7 @@ Anyway, here's the trick:
{{ hostvars[groups['webservers'][0]]['ansible_eth0']['ipv4']['address'] }} {{ hostvars[groups['webservers'][0]]['ansible_eth0']['ipv4']['address'] }}
Notice how we're pulling out the hostname of the first machine of the webservers group. If you are doing this in a template, you Notice how we're pulling out the hostname of the first machine of the webservers group. If you are doing this in a template, you
could use the Jinja2 '#set' directive to simplify this, or in a playbook, you could also use set_fact:: could use the Jinja2 '#set' directive to simplify this, or in a playbook, you could also use set_fact::
- set_fact: headnode={{ groups['webservers'][0] }} - set_fact: headnode={{ groups['webservers'][0] }}
@ -431,14 +452,16 @@ Notice how we interchanged the bracket syntax for dots -- that can be done anywh
How do I copy files recursively onto a target host? How do I copy files recursively onto a target host?
+++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++
The "copy" module has a recursive parameter. However, take a look at the "synchronize" module if you want to do something more efficient for a large number of files. The "synchronize" module wraps rsync. See the module index for info on both of these modules. The ``copy`` module has a recursive parameter. However, take a look at the ``synchronize`` module if you want to do something more efficient
for a large number of files. The ``synchronize`` module wraps rsync. See the module index for info on both of these modules.
.. _shell_env: .. _shell_env:
How do I access shell environment variables? How do I access shell environment variables?
++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++
If you just need to access existing variables ON THE CONTROLLER, use the 'env' lookup plugin.
**On controller machine :** Access existing variables from controller use the ``env`` lookup plugin.
For example, to access the value of the HOME environment variable on the management machine:: For example, to access the value of the HOME environment variable on the management machine::
--- ---
@ -447,15 +470,18 @@ For example, to access the value of the HOME environment variable on the managem
local_home: "{{ lookup('env','HOME') }}" local_home: "{{ lookup('env','HOME') }}"
For environment variables on the TARGET machines, they are available via facts in the 'ansible_env' variable: **On target machines :** Environment variables are available via facts in the ``ansible_env`` variable:
.. code-block:: jinja .. code-block:: jinja
{{ ansible_env.SOME_VARIABLE }} {{ ansible_env.HOME }}
If you need to set environment variables for TASK execution, see :ref:`playbooks_environment` in the :ref:`Advanced Playbooks <playbooks_special_topics>` section. If you need to set environment variables for TASK execution, see :ref:`playbooks_environment`
There are several ways to set environment variables on your target machines. You can use the :ref:`template <template_module>`, :ref:`replace <replace_module>`, or :ref:`lineinfile <lineinfile_module>` modules to introduce environment variables into files. in the :ref:`Advanced Playbooks <playbooks_special_topics>` section.
The exact files to edit vary depending on your OS and distribution and local configuration. There are several ways to set environment variables on your target machines. You can use the
:ref:`template <template_module>`, :ref:`replace <replace_module>`, or :ref:`lineinfile <lineinfile_module>`
modules to introduce environment variables into files. The exact files to edit vary depending on your OS
and distribution and local configuration.
.. _user_passwords: .. _user_passwords:
@ -468,7 +494,7 @@ Ansible ad-hoc command is the easiest option:
ansible all -i localhost, -m debug -a "msg={{ 'mypassword' | password_hash('sha512', 'mysecretsalt') }}" ansible all -i localhost, -m debug -a "msg={{ 'mypassword' | password_hash('sha512', 'mysecretsalt') }}"
The mkpasswd utility that is available on most Linux systems is also a great option: The ``mkpasswd`` utility that is available on most Linux systems is also a great option:
.. code-block:: shell-session .. code-block:: shell-session
@ -476,7 +502,7 @@ The mkpasswd utility that is available on most Linux systems is also a great opt
If this utility is not installed on your system (e.g. you are using macOS) then you can still easily If this utility is not installed on your system (e.g. you are using macOS) then you can still easily
generate these passwords using Python. First, ensure that the `Passlib <https://bitbucket.org/ecollins/passlib/wiki/Home>`_ generate these passwords using Python. First, ensure that the `Passlib <https://foss.heptapod.net/python-libs/passlib/-/wikis/home>`_
password hashing library is installed: password hashing library is installed:
.. code-block:: shell-session .. code-block:: shell-session
@ -492,11 +518,7 @@ Once the library is ready, SHA512 password values can then be generated as follo
Use the integrated :ref:`hash_filters` to generate a hashed version of a password. Use the integrated :ref:`hash_filters` to generate a hashed version of a password.
You shouldn't put plaintext passwords in your playbook or host_vars; instead, use :ref:`playbooks_vault` to encrypt sensitive data. You shouldn't put plaintext passwords in your playbook or host_vars; instead, use :ref:`playbooks_vault` to encrypt sensitive data.
In OpenBSD, a similar option is available in the base system called encrypt(1): In OpenBSD, a similar option is available in the base system called ``encrypt (1)``
.. code-block:: shell-session
encrypt
.. _dot_or_array_notation: .. _dot_or_array_notation:
@ -551,8 +573,11 @@ risky because the parameters and values passed to ``usermod_args`` could
be overwritten by malicious values in the ``host facts`` on a compromised be overwritten by malicious values in the ``host facts`` on a compromised
target machine. To mitigate this risk: target machine. To mitigate this risk:
* set bulk variables at a level of precedence greater than ``host facts`` in the order of precedence found in :ref:`ansible_variable_precedence` (the example above is safe because play vars take precedence over facts) * set bulk variables at a level of precedence greater than ``host facts`` in the order of precedence
* disable the :ref:`inject_facts_as_vars` configuration setting to prevent fact values from colliding with variables (this will also disable the original warning) found in :ref:`ansible_variable_precedence` (the example above is safe because play vars take
precedence over facts)
* disable the :ref:`inject_facts_as_vars` configuration setting to prevent fact values from colliding
with variables (this will also disable the original warning)
.. _commercial_support: .. _commercial_support:
@ -560,9 +585,11 @@ target machine. To mitigate this risk:
Can I get training on Ansible? Can I get training on Ansible?
++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++
Yes! See our `services page <https://www.ansible.com/products/consulting>`_ for information on our services and training offerings. Email `info@ansible.com <mailto:info@ansible.com>`_ for further details. Yes! See our `services page <https://www.ansible.com/products/consulting>`_ for information on our services
and training offerings. Email `info@ansible.com <mailto:info@ansible.com>`_ for further details.
We also offer free web-based training classes on a regular basis. See our `webinar page <https://www.ansible.com/resources/webinars-training>`_ for more info on upcoming webinars. We also offer free web-based training classes on a regular basis. See our
`webinar page <https://www.ansible.com/resources/webinars-training>`_ for more info on upcoming webinars.
.. _web_interface: .. _web_interface:
@ -570,15 +597,7 @@ We also offer free web-based training classes on a regular basis. See our `webin
Is there a web interface / REST API / etc? Is there a web interface / REST API / etc?
++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++
Yes! Ansible, Inc makes a great product that makes Ansible even more powerful and easy to use. See :ref:`ansible_tower`. Yes! Ansible, Inc makes a great product that makes Ansible even more powerful and easy to use. See :ref:`ansible_tower`.
.. _docs_contributions:
How do I submit a change to the documentation?
++++++++++++++++++++++++++++++++++++++++++++++
Great question! Documentation for Ansible is kept in the main project git repository, and complete instructions for contributing can be found in the docs README `viewable on GitHub <https://github.com/ansible/ansible/blob/devel/docs/docsite/README.md>`_. Thanks!
.. _keep_secret_data: .. _keep_secret_data:
@ -601,7 +620,7 @@ The ``no_log`` attribute can also apply to an entire play::
- hosts: all - hosts: all
no_log: True no_log: True
Though this will make the play somewhat difficult to debug. It's recommended that this Though this will make the play somewhat difficult to debug. It's recommended that this
be applied to single tasks only, once a playbook is completed. Note that the use of the be applied to single tasks only, once a playbook is completed. Note that the use of the
``no_log`` attribute does not prevent data from being shown when debugging Ansible itself via ``no_log`` attribute does not prevent data from being shown when debugging Ansible itself via
the :envvar:`ANSIBLE_DEBUG` environment variable. the :envvar:`ANSIBLE_DEBUG` environment variable.
@ -618,7 +637,8 @@ A steadfast rule is 'always use ``{{ }}`` except when ``when:``'.
Conditionals are always run through Jinja2 as to resolve the expression, Conditionals are always run through Jinja2 as to resolve the expression,
so ``when:``, ``failed_when:`` and ``changed_when:`` are always templated and you should avoid adding ``{{ }}``. so ``when:``, ``failed_when:`` and ``changed_when:`` are always templated and you should avoid adding ``{{ }}``.
In most other cases you should always use the brackets, even if previously you could use variables without specifying (like ``loop`` or ``with_`` clauses), as this made it hard to distinguish between an undefined variable and a string. In most other cases you should always use the brackets, even if previously you could use variables without
specifying (like ``loop`` or ``with_`` clauses), as this made it hard to distinguish between an undefined variable and a string.
Another rule is 'moustaches don't stack'. We often see this: Another rule is 'moustaches don't stack'. We often see this:
@ -641,10 +661,11 @@ For 'non host vars' you can use the :ref:`vars lookup<vars_lookup>` plugin:
.. _why_no_wheel: .. _why_no_wheel:
Why don't you ship in X format? Why don't you ship ansible in wheel format (or other packaging format) ?
+++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
In most cases it has to do with maintainability. There are many ways to ship software and we do not have the resources to release Ansible on every platform. In most cases it has to do with maintainability. There are many ways to ship software and we do not have
the resources to release Ansible on every platform.
In some cases there are technical issues. For example, our dependencies are not present on Python Wheels. In some cases there are technical issues. For example, our dependencies are not present on Python Wheels.
.. _ansible_host_delegated: .. _ansible_host_delegated:
@ -665,7 +686,8 @@ This works for all overridden connection variables, like ``ansible_user``, ``ans
How do I fix 'protocol error: filename does not match request' when fetching a file? How do I fix 'protocol error: filename does not match request' when fetching a file?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Newer releases of OpenSSH have a `bug <https://bugzilla.mindrot.org/show_bug.cgi?id=2966>`_ in the SCP client that can trigger this error on the Ansible controller when using SCP as the file transfer mechanism:: Since release ``7.9p1`` of OpenSSH there is a `bug <https://bugzilla.mindrot.org/show_bug.cgi?id=2966>`_
in the SCP client that can trigger this error on the Ansible controller when using SCP as the file transfer mechanism::
failed to transfer file to /tmp/ansible/file.txt\r\nprotocol error: filename does not match request failed to transfer file to /tmp/ansible/file.txt\r\nprotocol error: filename does not match request
@ -686,6 +708,14 @@ fails if the remote filename requires quotes to escape spaces or non-ascii chara
.. note:: If you see an ``invalid argument`` error when using ``-T``, then your SCP client is not performing filename validation and will not trigger this error. .. note:: If you see an ``invalid argument`` error when using ``-T``, then your SCP client is not performing filename validation and will not trigger this error.
.. _docs_contributions:
How do I submit a change to the documentation?
++++++++++++++++++++++++++++++++++++++++++++++
Documentation for Ansible is kept in the main project git repository, and complete instructions
for contributing can be found in the docs README `viewable on GitHub <https://github.com/ansible/ansible/blob/devel/docs/docsite/README.md>`_. Thanks!
.. _i_dont_see_my_question: .. _i_dont_see_my_question:
I don't see my question here I don't see my question here

@ -43,7 +43,7 @@ All tasks in a block inherit directives applied at the block level. Most of what
In the example above, the 'when' condition will be evaluated before Ansible runs each of the three tasks in the block. All three tasks also inherit the privilege escalation directives, running as the root user. Finally, ``ignore_errors: yes`` ensures that Ansible continues to execute the playbook even if some of the tasks fail. In the example above, the 'when' condition will be evaluated before Ansible runs each of the three tasks in the block. All three tasks also inherit the privilege escalation directives, running as the root user. Finally, ``ignore_errors: yes`` ensures that Ansible continues to execute the playbook even if some of the tasks fail.
Names for tasks within blocks have been available since Ansible 2.3. We recommend using names in all tasks, within blocks or elsewhere, for better visibility into the tasks being executed when you run the playbook. Names for blocks have been available since Ansible 2.3. We recommend using names in all tasks, within blocks or elsewhere, for better visibility into the tasks being executed when you run the playbook.
.. _block_error_handling: .. _block_error_handling:

@ -1511,6 +1511,14 @@ To get the root and extension of a path or file name (new in version 2.0)::
# with path == 'nginx.conf' the return would be ('nginx', '.conf') # with path == 'nginx.conf' the return would be ('nginx', '.conf')
{{ path | splitext }} {{ path | splitext }}
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 }}
# with path == 'nginx.conf' the return would be 'conf'
{{ path | splitext | last }}
To join one or more path components:: To join one or more path components::
{{ ('/etc', path, 'subdir', file) | path_join }} {{ ('/etc', path, 'subdir', file) | path_join }}

@ -235,7 +235,7 @@ To be prompted for a string to encrypt, encrypt it with the 'dev' vault password
The command above triggers this prompt: The command above triggers this prompt:
.. code-block:: bash .. code-block:: text
Reading plaintext input from stdin. (ctrl-d to end input) Reading plaintext input from stdin. (ctrl-d to end input)

@ -33,7 +33,7 @@ EXAMPLES = r"""
- name: Always use quote filter to make sure your variables are safe to use with shell - name: Always use quote filter to make sure your variables are safe to use with shell
debug: debug:
msg: "{{ lookup('pipe', 'getent ' + myuser | quote ) }}" msg: "{{ lookup('pipe', 'getent passwd ' + myuser | quote ) }}"
""" """
RETURN = r""" RETURN = r"""

Loading…
Cancel
Save