1.. _ansible_faq: 2 3Frequently Asked Questions 4========================== 5 6Here are some commonly asked questions and their answers. 7 8.. _collections_transition: 9 10Where did all the modules go? 11+++++++++++++++++++++++++++++ 12 13In July, 2019, we announced that collections would be the `future of Ansible content delivery <https://www.ansible.com/blog/the-future-of-ansible-content-delivery>`_. A collection is a distribution format for Ansible content that can include playbooks, roles, modules, and plugins. In Ansible 2.9 we added support for collections. In Ansible 2.10 we extracted most modules from the main ansible/ansible repository and placed them in :ref:`collections <list_of_collections>`. Collections may be maintained by the Ansible team, by the Ansible community, or by Ansible partners. The `ansible/ansible repository <https://github.com/ansible/ansible>`_ now contains the code for basic features and functions, such as copying module code to managed nodes. This code is also known as ``ansible-base``. 14 15* To learn more about using collections, see :ref:`collections`. 16* To learn more about developing collections, see :ref:`developing_collections`. 17* To learn more about contributing to existing collections, see the individual collection repository for guidelines, or see :ref:`contributing_maintained_collections` to contribute to one of the Ansible-maintained collections. 18 19.. _find_my_module: 20 21Where did this specific module go? 22++++++++++++++++++++++++++++++++++ 23 24IF you are searching for a specific module, you can check the `runtime.yml <https://github.com/ansible/ansible/blob/devel/lib/ansible/config/ansible_builtin_runtime.yml>`_ file, which lists the first destination for each module that we extracted from the main ansible/ansible repository. Some modules have moved again since then. You can also search on `Ansible Galaxy <https://galaxy.ansible.com/>`_ or ask on one of our :ref:`IRC channels <communication_irc>`. 25 26.. _set_environment: 27 28How can I set the PATH or any other environment variable for a task or entire play? 29+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 30 31Setting environment variables can be done with the `environment` keyword. It can be used at the task or other levels in the play. 32 33.. code-block:: yaml 34 35 shell: 36 cmd: date 37 environment: 38 LANG=fr_FR.UTF-8 39 40.. code-block:: yaml 41 42 hosts: servers 43 environment: 44 PATH: "{{ ansible_env.PATH }}:/thingy/bin" 45 SOME: value 46 47.. 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. 48 49.. _faq_setting_users_and_ports: 50 51How do I handle different machines needing different user accounts or ports to log in with? 52+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 53 54Setting inventory variables in the inventory file is the easiest way. 55 56For instance, suppose these hosts have different usernames and ports: 57 58.. code-block:: ini 59 60 [webservers] 61 asdf.example.com ansible_port=5000 ansible_user=alice 62 jkl.example.com ansible_port=5001 ansible_user=bob 63 64You can also dictate the connection type to be used, if you want: 65 66.. code-block:: ini 67 68 [testcluster] 69 localhost ansible_connection=local 70 /path/to/chroot1 ansible_connection=chroot 71 foo.example.com ansible_connection=paramiko 72 73You may also wish to keep these in group variables instead, or file them in a group_vars/<groupname> file. 74See the rest of the documentation for more information about how to organize variables. 75 76.. _use_ssh: 77 78How do I get ansible to reuse connections, enable Kerberized SSH, or have Ansible pay attention to my local SSH config file? 79++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 80 81Switch your default connection type in the configuration file to ``ssh``, or use ``-c ssh`` to use 82Native OpenSSH for connections instead of the python paramiko library. In Ansible 1.2.1 and later, ``ssh`` will be used 83by default if OpenSSH is new enough to support ControlPersist as an option. 84 85Paramiko is great for starting out, but the OpenSSH type offers many advanced options. You will want to run Ansible 86from a machine new enough to support ControlPersist, if you are using this connection type. You can still manage 87older clients. If you are using RHEL 6, CentOS 6, SLES 10 or SLES 11 the version of OpenSSH is still a bit old, so 88consider managing from a Fedora or openSUSE client even though you are managing older nodes, or just use paramiko. 89 90We 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. 91 92.. _use_ssh_jump_hosts: 93 94How do I configure a jump host to access servers that I have no direct access to? 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 96 97You can set a ``ProxyCommand`` in the 98``ansible_ssh_common_args`` inventory variable. Any arguments specified in 99this variable are added to the sftp/scp/ssh command line when connecting 100to the relevant host(s). Consider the following inventory group: 101 102.. code-block:: ini 103 104 [gatewayed] 105 foo ansible_host=192.0.2.1 106 bar ansible_host=192.0.2.2 107 108You can create `group_vars/gatewayed.yml` with the following contents:: 109 110 ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q user@gateway.example.com"' 111 112Ansible will append these arguments to the command line when trying to 113connect to any hosts in the group ``gatewayed``. (These arguments are used 114in addition to any ``ssh_args`` from ``ansible.cfg``, so you do not need to 115repeat global ``ControlPersist`` settings in ``ansible_ssh_common_args``.) 116 117Note that ``ssh -W`` is available only with OpenSSH 5.4 or later. With 118older versions, it's necessary to execute ``nc %h:%p`` or some equivalent 119command on the bastion host. 120 121With earlier versions of Ansible, it was necessary to configure a 122suitable ``ProxyCommand`` for one or more hosts in ``~/.ssh/config``, 123or globally by setting ``ssh_args`` in ``ansible.cfg``. 124 125.. _ssh_serveraliveinterval: 126 127How do I get Ansible to notice a dead target in a timely manner? 128++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 129 130You can add ``-o ServerAliveInterval=NumberOfSeconds`` in ``ssh_args`` from ``ansible.cfg``. Without this option, 131SSH and therefore Ansible will wait until the TCP connection times out. Another solution is to add ``ServerAliveInterval`` 132into your global SSH configuration. A good value for ``ServerAliveInterval`` is up to you to decide; keep in mind that 133``ServerAliveCountMax=3`` is the SSH default so any value you set will be tripled before terminating the SSH session. 134 135.. _cloud_provider_performance: 136 137How do I speed up run of ansible for servers from cloud providers (EC2, openstack,.. )? 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 139 140Don't try to manage a fleet of machines of a cloud provider from your laptop. 141Rather connect to a management node inside this cloud provider first and run Ansible from there. 142 143.. _python_interpreters: 144 145How do I handle not having a Python interpreter at /usr/bin/python on a remote machine? 146++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 147 148While you can write Ansible modules in any language, most Ansible modules are written in Python, 149including the ones central to letting Ansible work. 150 151By default, Ansible assumes it can find a :command:`/usr/bin/python` on your remote system that is 152either Python2, version 2.6 or higher or Python3, 3.5 or higher. 153 154Setting the inventory variable ``ansible_python_interpreter`` on any host will tell Ansible to 155auto-replace the Python interpreter with that value instead. Thus, you can point to any Python you 156want on the system if :command:`/usr/bin/python` on your system does not point to a compatible 157Python interpreter. 158 159Some platforms may only have Python 3 installed by default. If it is not installed as 160:command:`/usr/bin/python`, you will need to configure the path to the interpreter via 161``ansible_python_interpreter``. Although most core modules will work with Python 3, there may be some 162special purpose ones which do not or you may encounter a bug in an edge case. As a temporary 163workaround you can install Python 2 on the managed host and configure Ansible to use that Python via 164``ansible_python_interpreter``. If there's no mention in the module's documentation that the module 165requires Python 2, you can also report a bug on our `bug tracker 166<https://github.com/ansible/ansible/issues>`_ so that the incompatibility can be fixed in a future release. 167 168Do not replace the shebang lines of your python modules. Ansible will do this for you automatically at deploy time. 169 170Also, this works for ANY interpreter, for example ruby: ``ansible_ruby_interpreter``, perl: ``ansible_perl_interpreter``, and so on, 171so you can use this for custom modules written in any scripting language and control the interpreter location. 172 173Keep in mind that if you put ``env`` in your module shebang line (``#!/usr/bin/env <other>``), 174this facility will be ignored so you will be at the mercy of the remote `$PATH`. 175 176.. _installation_faqs: 177 178How do I handle the package dependencies required by Ansible package dependencies during Ansible installation ? 179+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 180 181While installing Ansible, sometimes you may encounter errors such as `No package 'libffi' found` or `fatal error: Python.h: No such file or directory` 182These errors are generally caused by the missing packages, which are dependencies of the packages required by Ansible. 183For example, `libffi` package is dependency of `pynacl` and `paramiko` (Ansible -> paramiko -> pynacl -> libffi). 184 185In order to solve these kinds of dependency issues, you might need to install required packages using 186the OS native package managers, such as `yum`, `dnf`, or `apt`, or as mentioned in the package installation guide. 187 188Refer to the documentation of the respective package for such dependencies and their installation methods. 189 190Common Platform Issues 191++++++++++++++++++++++ 192 193What customer platforms does Red Hat support? 194--------------------------------------------- 195 196A number of them! For a definitive list please see this `Knowledge Base article <https://access.redhat.com/articles/3168091>`_. 197 198Running in a virtualenv 199----------------------- 200 201You can install Ansible into a virtualenv on the controller quite simply: 202 203.. code-block:: shell 204 205 $ virtualenv ansible 206 $ source ./ansible/bin/activate 207 $ pip install ansible 208 209If you want to run under Python 3 instead of Python 2 you may want to change that slightly: 210 211.. code-block:: shell 212 213 $ virtualenv -p python3 ansible 214 $ source ./ansible/bin/activate 215 $ pip install ansible 216 217If you need to use any libraries which are not available via pip (for instance, SELinux Python 218bindings on systems such as Red Hat Enterprise Linux or Fedora that have SELinux enabled), then you 219need to install them into the virtualenv. There are two methods: 220 221* When you create the virtualenv, specify ``--system-site-packages`` to make use of any libraries 222 installed in the system's Python: 223 224 .. code-block:: shell 225 226 $ virtualenv ansible --system-site-packages 227 228* Copy those files in manually from the system. For instance, for SELinux bindings you might do: 229 230 .. code-block:: shell 231 232 $ virtualenv ansible --system-site-packages 233 $ cp -r -v /usr/lib64/python3.*/site-packages/selinux/ ./py3-ansible/lib64/python3.*/site-packages/ 234 $ cp -v /usr/lib64/python3.*/site-packages/*selinux*.so ./py3-ansible/lib64/python3.*/site-packages/ 235 236 237Running on BSD 238-------------- 239 240.. seealso:: :ref:`working_with_bsd` 241 242 243Running on Solaris 244------------------ 245 246By default, Solaris 10 and earlier run a non-POSIX shell which does not correctly expand the default 247tmp directory Ansible uses ( :file:`~/.ansible/tmp`). If you see module failures on Solaris machines, this 248is likely the problem. There are several workarounds: 249 250* You can set ``remote_tmp`` to a path that will expand correctly with the shell you are using 251 (see the plugin documentation for :ref:`C shell<csh_shell>`, :ref:`fish shell<fish_shell>`, 252 and :ref:`Powershell<powershell_shell>`). For example, in the ansible config file you can set:: 253 254 remote_tmp=$HOME/.ansible/tmp 255 256 In Ansible 2.5 and later, you can also set it per-host in inventory like this:: 257 258 solaris1 ansible_remote_tmp=$HOME/.ansible/tmp 259 260* You can set :ref:`ansible_shell_executable<ansible_shell_executable>` to the path to a POSIX compatible shell. For 261 instance, many Solaris hosts have a POSIX shell located at :file:`/usr/xpg4/bin/sh` so you can set 262 this in inventory like so:: 263 264 solaris1 ansible_shell_executable=/usr/xpg4/bin/sh 265 266 (bash, ksh, and zsh should also be POSIX compatible if you have any of those installed). 267 268Running on z/OS 269--------------- 270 271There are a few common errors that one might run into when trying to execute Ansible on z/OS as a target. 272 273* Version 2.7.6 of python for z/OS will not work with Ansible because it represents strings internally as EBCDIC. 274 275 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. 276 277* When ``pipelining = False`` in `/usr/local/etc/ansible/ansible.cfg` then Ansible modules are transferred in binary mode via sftp however execution of python fails with 278 279 .. error:: 280 SyntaxError: Non-UTF-8 code starting with \'\\x83\' in file /a/user1/.ansible/tmp/ansible-tmp-1548232945.35-274513842609025/AnsiballZ_stat.py on line 1, but no encoding declared; see https://python.org/dev/peps/pep-0263/ for details 281 282 To fix it set ``pipelining = True`` in `/usr/local/etc/ansible/ansible.cfg`. 283 284* Python interpret cannot be found in default location ``/usr/bin/python`` on target host. 285 286 .. error:: 287 /usr/bin/python: EDC5129I No such file or directory 288 289 To fix this set the path to the python installation in your inventory like so:: 290 291 zos1 ansible_python_interpreter=/usr/lpp/python/python-2017-04-12-py27/python27/bin/python 292 293* Start of python fails with ``The module libpython2.7.so was not found.`` 294 295 .. error:: 296 EE3501S The module libpython2.7.so was not found. 297 298 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``:: 299 300 zos1 ansible_shell_executable=/usr/lpp/bash/bin/bash 301 302 303Running under fakeroot 304---------------------- 305 306Some issues arise as ``fakeroot`` does not create a full nor POSIX compliant system by default. 307It is known that it will not correctly expand the default tmp directory Ansible uses (:file:`~/.ansible/tmp`). 308If you see module failures, this is likely the problem. 309The simple workaround is to set ``remote_tmp`` to a path that will expand correctly (see documentation of the shell plugin you are using for specifics). 310 311For example, in the ansible config file (or via environment variable) you can set:: 312 313 remote_tmp=$HOME/.ansible/tmp 314 315 316 317.. _use_roles: 318 319What is the best way to make content reusable/redistributable? 320++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 321 322If you have not done so already, read all about "Roles" in the playbooks documentation. This helps you make playbook content 323self-contained, and works well with things like git submodules for sharing content with others. 324 325If some of these plugin types look strange to you, see the API documentation for more details about ways Ansible can be extended. 326 327.. _configuration_file: 328 329Where does the configuration file live and what can I configure in it? 330++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 331 332 333See :ref:`intro_configuration`. 334 335.. _who_would_ever_want_to_disable_cowsay_but_ok_here_is_how: 336 337How do I disable cowsay? 338++++++++++++++++++++++++ 339 340If cowsay is installed, Ansible takes it upon itself to make your day happier when running playbooks. If you decide 341that you would like to work in a professional cow-free environment, you can either uninstall cowsay, set ``nocows=1`` 342in ``ansible.cfg``, or set the :envvar:`ANSIBLE_NOCOWS` environment variable: 343 344.. code-block:: shell-session 345 346 export ANSIBLE_NOCOWS=1 347 348.. _browse_facts: 349 350How do I see a list of all of the ansible\_ variables? 351++++++++++++++++++++++++++++++++++++++++++++++++++++++ 352 353Ansible by default gathers "facts" about the machines under management, and these facts can be accessed in playbooks 354and in templates. To see a list of all of the facts that are available about a machine, you can run the ``setup`` module 355as an ad-hoc action: 356 357.. code-block:: shell-session 358 359 ansible -m setup hostname 360 361This will print out a dictionary of all of the facts that are available for that particular host. You might want to pipe 362the output to a pager.This does NOT include inventory variables or internal 'magic' variables. See the next question 363if you need more than just 'facts'. 364 365 366.. _browse_inventory_vars: 367 368How do I see all the inventory variables defined for my host? 369+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 370 371By running the following command, you can see inventory variables for a host: 372 373.. code-block:: shell-session 374 375 ansible-inventory --list --yaml 376 377 378.. _browse_host_vars: 379 380How do I see all the variables specific to my host? 381+++++++++++++++++++++++++++++++++++++++++++++++++++ 382 383To see all host specific variables, which might include facts and other sources: 384 385.. code-block:: shell-session 386 387 ansible -m debug -a "var=hostvars['hostname']" localhost 388 389Unless you are using a fact cache, you normally need to use a play that gathers facts first, for facts included in the task above. 390 391 392.. _host_loops: 393 394How do I loop over a list of hosts in a group, inside of a template? 395++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 396 397A pretty common pattern is to iterate over a list of hosts inside of a host group, perhaps to populate a template configuration 398file with a list of servers. To do this, you can just access the "$groups" dictionary in your template, like this: 399 400.. code-block:: jinja 401 402 {% for host in groups['db_servers'] %} 403 {{ host }} 404 {% endfor %} 405 406If you need to access facts about these hosts, for instance, the IP address of each hostname, 407you need to make sure that the facts have been populated. For example, make sure you have a play that talks to db_servers:: 408 409 - hosts: db_servers 410 tasks: 411 - debug: msg="doesn't matter what you do, just that they were talked to previously." 412 413Then you can use the facts inside your template, like this: 414 415.. code-block:: jinja 416 417 {% for host in groups['db_servers'] %} 418 {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }} 419 {% endfor %} 420 421.. _programatic_access_to_a_variable: 422 423How do I access a variable name programmatically? 424+++++++++++++++++++++++++++++++++++++++++++++++++ 425 426An 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 427via a role parameter or other input. Variable names can be built by adding strings together, like so: 428 429.. code-block:: jinja 430 431 {{ hostvars[inventory_hostname]['ansible_' + which_interface]['ipv4']['address'] }} 432 433The trick about going through hostvars is necessary because it's a dictionary of the entire namespace of variables. ``inventory_hostname`` 434is a magic variable that indicates the current host you are looping over in the host loop. 435 436In the example above, if your interface names have dashes, you must replace them with underscores: 437 438.. code-block:: jinja 439 440 {{ hostvars[inventory_hostname]['ansible_' + which_interface | replace('_', '-') ]['ipv4']['address'] }} 441 442Also see dynamic_variables_. 443 444 445.. _access_group_variable: 446 447How do I access a group variable? 448+++++++++++++++++++++++++++++++++ 449 450Technically, you don't, Ansible does not really use groups directly. Groups are labels for host selection and a way to bulk assign variables, 451they are not a first class entity, Ansible only cares about Hosts and Tasks. 452 453That 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. 454 455 456.. _first_host_in_a_group: 457 458How do I access a variable of the first host in a group? 459++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 460 461What 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 462are using dynamic inventory, which host is the 'first' may not be consistent, so you wouldn't want to do this unless your inventory 463is 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 464based inventory scripts). 465 466Anyway, here's the trick: 467 468.. code-block:: jinja 469 470 {{ hostvars[groups['webservers'][0]]['ansible_eth0']['ipv4']['address'] }} 471 472Notice how we're pulling out the hostname of the first machine of the webservers group. If you are doing this in a template, you 473could use the Jinja2 '#set' directive to simplify this, or in a playbook, you could also use set_fact:: 474 475 - set_fact: headnode={{ groups['webservers'][0] }} 476 477 - debug: msg={{ hostvars[headnode].ansible_eth0.ipv4.address }} 478 479Notice how we interchanged the bracket syntax for dots -- that can be done anywhere. 480 481.. _file_recursion: 482 483How do I copy files recursively onto a target host? 484+++++++++++++++++++++++++++++++++++++++++++++++++++ 485 486The ``copy`` module has a recursive parameter. However, take a look at the ``synchronize`` module if you want to do something more efficient 487for a large number of files. The ``synchronize`` module wraps rsync. See the module index for info on both of these modules. 488 489.. _shell_env: 490 491How do I access shell environment variables? 492++++++++++++++++++++++++++++++++++++++++++++ 493 494 495**On controller machine :** Access existing variables from controller use the ``env`` lookup plugin. 496For example, to access the value of the HOME environment variable on the management machine:: 497 498 --- 499 # ... 500 vars: 501 local_home: "{{ lookup('env','HOME') }}" 502 503 504**On target machines :** Environment variables are available via facts in the ``ansible_env`` variable: 505 506.. code-block:: jinja 507 508 {{ ansible_env.HOME }} 509 510If you need to set environment variables for TASK execution, see :ref:`playbooks_environment` 511in the :ref:`Advanced Playbooks <playbooks_special_topics>` section. 512There are several ways to set environment variables on your target machines. You can use the 513:ref:`template <template_module>`, :ref:`replace <replace_module>`, or :ref:`lineinfile <lineinfile_module>` 514modules to introduce environment variables into files. The exact files to edit vary depending on your OS 515and distribution and local configuration. 516 517.. _user_passwords: 518 519How do I generate encrypted passwords for the user module? 520++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 521 522Ansible ad-hoc command is the easiest option: 523 524.. code-block:: shell-session 525 526 ansible all -i localhost, -m debug -a "msg={{ 'mypassword' | password_hash('sha512', 'mysecretsalt') }}" 527 528The ``mkpasswd`` utility that is available on most Linux systems is also a great option: 529 530.. code-block:: shell-session 531 532 mkpasswd --method=sha-512 533 534 535If this utility is not installed on your system (for example, you are using macOS) then you can still easily 536generate these passwords using Python. First, ensure that the `Passlib <https://foss.heptapod.net/python-libs/passlib/-/wikis/home>`_ 537password hashing library is installed: 538 539.. code-block:: shell-session 540 541 pip install passlib 542 543Once the library is ready, SHA512 password values can then be generated as follows: 544 545.. code-block:: shell-session 546 547 python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))" 548 549Use the integrated :ref:`hash_filters` to generate a hashed version of a password. 550You shouldn't put plaintext passwords in your playbook or host_vars; instead, use :ref:`playbooks_vault` to encrypt sensitive data. 551 552In OpenBSD, a similar option is available in the base system called ``encrypt (1)`` 553 554.. _dot_or_array_notation: 555 556Ansible allows dot notation and array notation for variables. Which notation should I use? 557++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 558 559The dot notation comes from Jinja and works fine for variables without special 560characters. If your variable contains dots (.), colons (:), or dashes (-), if 561a key begins and ends with two underscores, or if a key uses any of the known 562public attributes, it is safer to use the array notation. See :ref:`playbooks_variables` 563for a list of the known public attributes. 564 565.. code-block:: jinja 566 567 item[0]['checksum:md5'] 568 item['section']['2.1'] 569 item['region']['Mid-Atlantic'] 570 It is {{ temperature['Celsius']['-3'] }} outside. 571 572Also array notation allows for dynamic variable composition, see dynamic_variables_. 573 574Another problem with 'dot notation' is that some keys can cause problems because they collide with attributes and methods of python dictionaries. 575 576.. code-block:: jinja 577 578 item.update # this breaks if item is a dictionary, as 'update()' is a python method for dictionaries 579 item['update'] # this works 580 581 582.. _argsplat_unsafe: 583 584When is it unsafe to bulk-set task arguments from a variable? 585+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 586 587 588You can set all of a task's arguments from a dictionary-typed variable. This 589technique can be useful in some dynamic execution scenarios. However, it 590introduces a security risk. We do not recommend it, so Ansible issues a 591warning when you do something like this:: 592 593 #... 594 vars: 595 usermod_args: 596 name: testuser 597 state: present 598 update_password: always 599 tasks: 600 - user: '{{ usermod_args }}' 601 602This particular example is safe. However, constructing tasks like this is 603risky because the parameters and values passed to ``usermod_args`` could 604be overwritten by malicious values in the ``host facts`` on a compromised 605target machine. To mitigate this risk: 606 607* set bulk variables at a level of precedence greater than ``host facts`` in the order of precedence 608 found in :ref:`ansible_variable_precedence` (the example above is safe because play vars take 609 precedence over facts) 610* disable the :ref:`inject_facts_as_vars` configuration setting to prevent fact values from colliding 611 with variables (this will also disable the original warning) 612 613 614.. _commercial_support: 615 616Can I get training on Ansible? 617++++++++++++++++++++++++++++++ 618 619Yes! See our `services page <https://www.ansible.com/products/consulting>`_ for information on our services 620and training offerings. Email `info@ansible.com <mailto:info@ansible.com>`_ for further details. 621 622We also offer free web-based training classes on a regular basis. See our 623`webinar page <https://www.ansible.com/resources/webinars-training>`_ for more info on upcoming webinars. 624 625 626.. _web_interface: 627 628Is there a web interface / REST API / GUI? 629++++++++++++++++++++++++++++++++++++++++++++ 630 631Yes! Ansible, Inc makes a great product that makes Ansible even more powerful and easy to use. See :ref:`ansible_tower`. 632 633 634.. _keep_secret_data: 635 636How do I keep secret data in my playbook? 637+++++++++++++++++++++++++++++++++++++++++ 638 639If you would like to keep secret data in your Ansible content and still share it publicly or keep things in source control, see :ref:`playbooks_vault`. 640 641If you have a task that you don't want to show the results or command given to it when using -v (verbose) mode, the following task or playbook attribute can be useful:: 642 643 - name: secret task 644 shell: /usr/bin/do_something --value={{ secret_value }} 645 no_log: True 646 647This can be used to keep verbose output but hide sensitive information from others who would otherwise like to be able to see the output. 648 649The ``no_log`` attribute can also apply to an entire play:: 650 651 - hosts: all 652 no_log: True 653 654Though this will make the play somewhat difficult to debug. It's recommended that this 655be applied to single tasks only, once a playbook is completed. Note that the use of the 656``no_log`` attribute does not prevent data from being shown when debugging Ansible itself via 657the :envvar:`ANSIBLE_DEBUG` environment variable. 658 659 660.. _when_to_use_brackets: 661.. _dynamic_variables: 662.. _interpolate_variables: 663 664When should I use {{ }}? Also, how to interpolate variables or dynamic variable names 665+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 666 667A steadfast rule is 'always use ``{{ }}`` except when ``when:``'. 668Conditionals are always run through Jinja2 as to resolve the expression, 669so ``when:``, ``failed_when:`` and ``changed_when:`` are always templated and you should avoid adding ``{{ }}``. 670 671In most other cases you should always use the brackets, even if previously you could use variables without 672specifying (like ``loop`` or ``with_`` clauses), as this made it hard to distinguish between an undefined variable and a string. 673 674Another rule is 'moustaches don't stack'. We often see this: 675 676.. code-block:: jinja 677 678 {{ somevar_{{other_var}} }} 679 680The above DOES NOT WORK as you expect, if you need to use a dynamic variable use the following as appropriate: 681 682.. code-block:: jinja 683 684 {{ hostvars[inventory_hostname]['somevar_' + other_var] }} 685 686For 'non host vars' you can use the :ref:`vars lookup<vars_lookup>` plugin: 687 688.. code-block:: jinja 689 690 {{ lookup('vars', 'somevar_' + other_var) }} 691 692 693.. _why_no_wheel: 694 695Why don't you ship ansible in wheel format (or other packaging format) ? 696++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 697 698In most cases it has to do with maintainability. There are many ways to ship software and we do not have 699the resources to release Ansible on every platform. 700In some cases there are technical issues. For example, our dependencies are not present on Python Wheels. 701 702.. _ansible_host_delegated: 703 704How do I get the original ansible_host when I delegate a task? 705++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 706 707As the documentation states, connection variables are taken from the ``delegate_to`` host so ``ansible_host`` is overwritten, 708but you can still access the original via ``hostvars``:: 709 710 original_host: "{{ hostvars[inventory_hostname]['ansible_host'] }}" 711 712This works for all overridden connection variables, like ``ansible_user``, ``ansible_port``, and so on. 713 714 715.. _scp_protocol_error_filename: 716 717How do I fix 'protocol error: filename does not match request' when fetching a file? 718++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 719 720Since release ``7.9p1`` of OpenSSH there is a `bug <https://bugzilla.mindrot.org/show_bug.cgi?id=2966>`_ 721in the SCP client that can trigger this error on the Ansible controller when using SCP as the file transfer mechanism:: 722 723 failed to transfer file to /tmp/ansible/file.txt\r\nprotocol error: filename does not match request 724 725In these releases, SCP tries to validate that the path of the file to fetch matches the requested path. 726The validation 727fails if the remote filename requires quotes to escape spaces or non-ascii characters in its path. To avoid this error: 728 729* Use SFTP instead of SCP by setting ``scp_if_ssh`` to ``smart`` (which tries SFTP first) or to ``False``. You can do this in one of four ways: 730 * Rely on the default setting, which is ``smart`` - this works if ``scp_if_ssh`` is not explicitly set anywhere 731 * Set a :ref:`host variable <host_variables>` or :ref:`group variable <group_variables>` in inventory: ``ansible_scp_if_ssh: False`` 732 * Set an environment variable on your control node: ``export ANSIBLE_SCP_IF_SSH=False`` 733 * Pass an environment variable when you run Ansible: ``ANSIBLE_SCP_IF_SSH=smart ansible-playbook`` 734 * Modify your ``ansible.cfg`` file: add ``scp_if_ssh=False`` to the ``[ssh_connection]`` section 735* If you must use SCP, set the ``-T`` arg to tell the SCP client to ignore path validation. You can do this in one of three ways: 736 * Set a :ref:`host variable <host_variables>` or :ref:`group variable <group_variables>`: ``ansible_scp_extra_args=-T``, 737 * Export or pass an environment variable: ``ANSIBLE_SCP_EXTRA_ARGS=-T`` 738 * Modify your ``ansible.cfg`` file: add ``scp_extra_args=-T`` to the ``[ssh_connection]`` section 739 740.. 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. 741 742.. _docs_contributions: 743 744How do I submit a change to the documentation? 745++++++++++++++++++++++++++++++++++++++++++++++ 746 747Documentation for Ansible is kept in the main project git repository, and complete instructions 748for contributing can be found in the docs README `viewable on GitHub <https://github.com/ansible/ansible/blob/devel/docs/docsite/README.md>`_. Thanks! 749 750.. _i_dont_see_my_question: 751 752I don't see my question here 753++++++++++++++++++++++++++++ 754 755Please see the section below for a link to IRC and the Google Group, where you can ask your question there. 756 757.. seealso:: 758 759 :ref:`working_with_playbooks` 760 An introduction to playbooks 761 :ref:`playbooks_best_practices` 762 Tips and tricks for playbooks 763 `User Mailing List <https://groups.google.com/group/ansible-project>`_ 764 Have a question? Stop by the google group! 765 `irc.libera.chat <https://libera.chat/>`_ 766 #ansible IRC chat channel 767