1

I want to be able to change the userid within a playbook and then get the home directory on a host for that userid. How would I do this?

I know I can change the userid with 'become:' and 'become_user:', but that works at the task level. I can get the home directory with the '{{ lookup('env', 'HOME) }}' variable, but that seems to work at the playbook level. This was my latest attempt:

---
- hosts: all
  vars:
       user_id: "{{ userid }}"
  tasks:
  - set_fact:
        home_dir: "{{ lookup('env', 'HOME') }}"
    become: yes
    become_user: "{{ user_id }}"
  - debug:
        msg: "Variable values: user_id: {{ user_id }}  home_dir: {{ home_dir }}"

My command looked like this:

$ ansible-playbook myplaybook.yaml --limit MYHOSTS --extra-vars "userid=myid"

This was the response:

ok: [host-01] => {
    "msg": "Variable values: user_id: myid  home_dir: /root"
 }
ok: [host-02] => {
    "msg": "Variable values: user_id: myid  home_dir: /root"
}
ok: [host-03] => {
    "msg": "Variable values: user_id: myid home_dir: /root"
}

Is there a way I can change the userid to "myid" and get the playbook to know that the home directory is "/home/myid"?

Thanks!

awrobinson
  • 765
  • 2
  • 8
  • 11

1 Answers1

2

When you use become and become_user, you're actually telling Ansible to change the current user, from what it initially logged-in with.
As per Ansible Docs:

These Directives (become, become_user, etc.) can be set from play to task level, but are overridden by connection variables as they can be host specific.

You must also note that by using the above syntax, you are actually activating a privilege escalation method, to become a non-privileged user. This is rather risky with quite a few limitation. Please read here: Becoming an Unprivileged User.

I hope the following play, will give you clearer picture:

---
- hosts: all
  gather_facts: no
  remote_user: "{{ userid }}"  

  tasks:
    - name: first_task
      register: first_task
      shell: "whoami"

    - name: become-root
      register: become-root
      shell: "whoami"
      become: yes
      become_user: root

    - name: final_task
      register: final_task
      shell: "whoami"

You should run the above, by executing this command:

# ansible-playbook playbook.yaml -i /path/to/inventory/hosts -e "userid=myid"

It will return:
first_task --> myid
become-root --> root
final_task --> myid
Note: You can also override remote_user, separately for each task.


But if you still require to do it your own way, you can try this one:

---
- hosts: all
  vars:
    user_id: "{{ userid }}"

  tasks:
    - set_fact:
         home_dir: "{{ lookup('env', 'HOME') }}"
      become: true

    - debug:
         msg: "Variable values: user_id: {{ userid }}  home_dir: {{ home_dir }}"
         when: userid is defined

Run with this command:

# ansible-playbook myplaybook.yaml -i path/to/inventory/hosts --limit MYHOSTS --become-user=myid --extra-vars "userid=myid"

And finally, if none of these did what you were after, try getting the home directory, by using the command module and then retrieve its output by first registering it, and then using {{ registered_name.stdout_lines }}:

- name: user_home
  register: user_home
  action: command eval echo "~{{ userid }}"

- debug:
     msg: "Home path is {{ user_home.stdout_lines }}

Using this last workaround, you don't even need to change user as it prints out the home directory for user userid.

# ansible-playbook myplaybook.yaml -i path/to/inventory/hosts --limit MYHOSTS -e "userid=myid"

Hope it helped; but this very question was asked before. You might be able to find more details here: How to switch a user per task or set of tasks?.

Sam
  • 71
  • 5