112

I'm scripting a deployment process that takes the name of the user running the ansible script (e.g. tlau) and creates a deployment directory on the remote system based on that username and the current date/time (e.g. tlau-deploy-2014-10-15-16:52).

You would think this is available in ansible facts (e.g. LOGNAME or SUDO_USER), but those are all set to either "root" or the deployment id being used to ssh into the remote system. None of those contain the local user, the one who is currently running the ansible process.

How can I script getting the name of the user running the ansible process and use it in my playbook?

AdrianHHH
  • 13,492
  • 16
  • 50
  • 87
Tessa Lau
  • 1,469
  • 2
  • 12
  • 15

7 Answers7

142

If you gather_facts, which is enabled by default for playbooks, there is a built-in variable that is set called ansible_user_id that provides the user name that the tasks are being run as. You can then use this variable in other tasks or templates with {{ ansible_user_id }}. This would save you the step of running a task to register that variable.

See: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variables-discovered-from-systems-facts

darkdragon
  • 392
  • 5
  • 13
Tony Cesaro
  • 1,730
  • 1
  • 10
  • 12
  • 25
    For future references, this returns the name of the user on the managed machine aka same as the `remote_user`, not the user on the host machine. To get the user name on the host machine, I don't see an alternative to a `local_action` as explained by @Ramon. – astorije Mar 11 '15 at 04:39
  • 48
    An alternative to lookup the user on localhost running ansible is to use lookup: {{ lookup('env', 'USER') }} http://docs.ansible.com/ansible/playbooks_lookups.html – Budric Mar 17 '16 at 17:03
  • 10
    @Budric In my opinion this should be posted as an answer – 030 Jul 19 '16 at 16:55
  • 19
    However `{{ansible_user_id}}` ends up being "root" if you `become:yes` – Stephen Ostermiller Aug 08 '17 at 19:08
  • 9
    In Ansible 2.8.3, `ansible_user_id` does _not_ seem to end up being root even with `become: yes`. – David Oliver Aug 14 '19 at 20:24
  • 1
    This depend on with which user the `setup` module was executed. The system facts are garthered at then beginning. If the intial user was `root` and `gather_facts` was ran, it is going to be `root`. If the initial user was `joe`, it's gonna be `joe`. It does not matter if `become` was on/off at the task where the fact is used. – udondan Sep 08 '19 at 13:23
  • 1
    In my testing (Ansible 2.8.5), setting `become: yes` at the playbook level makes `ansible_user_id` "root" even if the task has `become: no`. The only reliable way I've found to get the real username is via the env lookup as in @Budric's comment above. – cfiske Sep 25 '19 at 21:18
  • 1
    Watch out for the `gathering` setting in section `defaults` of the `ansible.cfg` file! Setting it to `implicit` always returns the effective `ansible_user_id` while `smart` (desirable for performance reasons) yields the user running the facts gathering. – Stephan Oct 17 '22 at 19:23
  • Will `{{ ansible_user_id }}` not be the user id on the localhost if I use `delegate_to: localhost` ? – Johannes Schaub - litb Jun 06 '23 at 17:15
107

If you mean the username on the host system, there are two options:

You can run a local action (which runs on the host machine rather than the target machine):

- name: get the username running the deploy
  become: false
  local_action: command whoami
  register: username_on_the_host

- debug: var=username_on_the_host

In this example, the output of the whoami command is registered in a variable called "username_on_the_host", and the username will be contained in username_on_the_host.stdout.

(the debug task is not required here, it just demonstrates the content of the variable)


The second options is to use a "lookup plugin":

{{ lookup('env', 'USER') }}

Read about lookup plugins here: docs.ansible.com/ansible/playbooks_lookups.html

Ramon de la Fuente
  • 8,044
  • 3
  • 32
  • 31
57

I put something like the following in all templates:

# Placed here by {{ lookup('env','USER') }} using Ansible, {{ ansible_date_time.date }}.

When templated over it shows up as:

# Placed here by staylorx using Ansible, 2017-01-11.

If I use {{ ansible_user_id }} and I've become root then that variable indicates "root", not what I want most of the time.

staylorx
  • 1,188
  • 12
  • 13
  • You can also add this lookup in a var at the beginning of the playbook in a `vars` section. Like this : ``` - hosts: xxx gather_facts: no vars: user: "{{ lookup('env','USER') }}" ``` – Bludwarf Jul 31 '17 at 15:44
  • you can use the jinja2 comment filter and the ansible_managed variable which is described in the documentation http://docs.ansible.com/ansible/latest/playbooks_filters.html#comment-filter (search for ansible_managed) – dtrv Jan 11 '18 at 14:23
10

This seems to work for me (ansible 2.9.12):

- name: get the non root remote user
  set_fact:
    remote_regular_user: "{{ ansible_env.SUDO_USER or ansible_user_id }}"

You can also simply set this as a variable - e.g. in your group_vars/all.yml:

remote_regular_user: "{{ ansible_env.SUDO_USER or ansible_user_id }}"
tshalif
  • 2,277
  • 2
  • 15
  • 10
  • Just ran into a use case (calling a playbook from a script which required sudo) where `ansible_env.SUDO_USER` was the only thing that held the correct info. +1 for falling back to `ansible_user_id` which works the other 99.99% of the time. – Dale C. Anderson Dec 31 '22 at 01:52
6

This reads the user name from the remote system, because it is not guaranteed, that the user names on the local and the remote system are the same. It is possible to change the name in the SSH configuration.

- name: Run whoami without become.
  command: whoami
  changed_when: false
  become: false
  register: whoami

- name: Set a fact with the user name.
  set_fact:
    login_user: "{{ whoami.stdout }}"
ceving
  • 21,900
  • 13
  • 104
  • 178
1

if you want to get the user who run the template in ansible tower you could use this var {{tower_user_name}} in your playbook but it´s only defined on manually executions

tower_user_name :The user name of the Tower user that started this job. This is not available for callback or scheduled jobs.

check this docs https://docs.ansible.com/ansible-tower/latest/html/userguide/job_templates.html

1

When you use the "become" option to launch Ansible or run a task, the logged in user will change to the user you are changing to (typically root). To get the name of the original user used to log in to the remote host with (ie: before escalating) you can use the ansible_user special variable. In addition, if you want to gather facts for a specific user other than the one currently running a task, you can use the user built-in module by doing something like this:

- user
    name: "username"
  register: user_data

Now the user_data fact contains a bunch of useful information about that user, including their uid, gid, home folder, and a bunch of other stuff. See the return value for this task in the docs for details. Using this technique, you can get details about the original user Ansible was launched with by doing something like this:

- user
    name: "{{ ansible_user }}"
  register: user_data

Conversely, if all you want is the name of the active user that is running a specific task (ie: which accounts for any user-switches that occur with the "become" operation) you can use the ansible_user_id fact instead.

leedega
  • 31
  • 3