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