gathering smart and ansible_env behaviour

Hi,

Encountered somewhat surprising behaviour regarding what happens when you enable smart fact gathering, have some plays using ‘become: yes’ at the top level along with using ansible_env[‘USER’] and ansible_env[‘HOME’].

I say surprising, because although it’s clear what happens once you understand what’s going on, it’s not really “behaviour of least surprise” when creating playbooks and roles for maximum reuse.

The Example

Taking the following play:

What you are proposing would require that every task gather facts
before running, that would be very slow and require at least double
the number of connections.

I don’t think it would need to query such information on every task execution.

Ansible already gathers env facts one user, why not have that to gather the env facts for both the become and remote user at the same time, with added option to list additional users to include as well, in case someone wants to change the become user for tasks subsequently, and have a way of making that information available to tasks run for where access to the environment settings is needed without overwriting the view presented to subsequent tasks when using fact caching.

Sure it might be useful to automatically gather the env information for the become_user if it’s not already retrieved as part of the initial fact gathering, but that would only result in every task gathering additional facts if you used a different become_user for each task. If this was added, making it optional and default to off would make sense. I would consider it a bit like the idea of only gathering host facts if not already gathered, but just applied to the user level as well.

Also provide some variables that identify the remote and become users separately and consistently instead of the current situation where with smart fact gathering the value of ansible_user_* can change depending on whether become was set to yes or no with the last fact gathering on that host during the same run. That makes ansible_env and ansible_user_* trickier to use for re-usability without causing surprises.

Right now when that situation occurs, to prevent odd behaviour in following plays expecting the default ansible_env to reflect the remote user, would need to force gather_facts for the play with become set to yes, followed by a subsequent force gather_facts with become set to no.

I think it should be possible to provide consistent behaviour, even if that may mean that you may need to explicitly gather the env info for a particular user.

If ansible exposed both the become_user and remote_user and also had a variable that reflected what user a task was going to be run using, then I might be able to put together some custom fact gathering for local use that would ensure consistency around ensuring that the env variables being accessed matched the task user provided we used a particular pattern to access.