Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get an arbitrary remote user's home directory in Ansible?

I can do that with shell using combination of getent and awk like this:

getent passwd $user | awk -F: '{ print $6 }' 

For the reference, in Puppet I can use a custom fact, like this:

require 'etc'  Etc.passwd { |user|     Facter.add("home_#{user.name}") do       setcode do          user.dir       end    end  } 

which makes the user's home directory available as a home_<user name> fact.

How do I get the home directory of an arbitrary remote user?

like image 680
Adam Ryczkowski Avatar asked Oct 26 '15 10:10

Adam Ryczkowski


People also ask

What is Ansible_env home?

ansible_env. HOME does return the HOME of the remote user (but it is not affected by become ). However lookup('env','HOME') returns the HOME of the user running the playbook at the controller.

What does Set_fact do in ansible?

This module allows setting new variables. Variables are set on a host-by-host basis just like facts discovered by the setup module. These variables will be available to subsequent plays during an ansible-playbook run.

How do I see ansible environment variables?

You can access the environment variables available on the local server via the 'lookup' plugins, which allow you to access the system data, and 'env' plugin which is written for accessing the environment variables.

What is Run_once in ansible?

Ansible run_once parameter is used with a task, which you want to run once on first host. When used, this forces the Ansible controller to attempt execution on first host in the current hosts batch, then the result can be applied to the other remaining hosts in current batch.


2 Answers

Ansible (from 1.4 onwards) already reveals environment variables for the user under the ansible_env variable.

- hosts: all   tasks:     - name: debug through ansible.env       debug: var=ansible_env.HOME 

Unfortunately you can apparently only use this to get environment variables for the connected user as this playbook and output shows:

- hosts: all   tasks:     - name: debug specified user's home dir through ansible.env       debug: var=ansible_env.HOME       become: true       become_user: "{{ user }}"      - name: debug specified user's home dir through lookup on env       debug: var=lookup('env','HOME')       become: true       become_user: "{{ user }}" 

OUTPUT:

vagrant@Test-01:~$ ansible-playbook -i "inventory/vagrant" env_vars.yml -e "user=testuser"  PLAY [all] ********************************************************************  GATHERING FACTS *************************************************************** ok: [192.168.0.30]  TASK: [debug specified user's home dir through ansible.env] ******************* ok: [192.168.0.30] => {     "var": {         "/home/vagrant": "/home/vagrant"     } }  TASK: [debug specified user's home dir through lookup on env] ***************** ok: [192.168.0.30] => {     "var": {         "/home/vagrant": "/home/vagrant"     } }  PLAY RECAP ******************************************************************** 192.168.0.30               : ok=3    changed=0    unreachable=0    failed=0 

As with anything in Ansible, if you can't get a module to give you what you want then you are always free to shell out (although this should be used sparingly as it may be fragile and will be less descriptive) using something like this:

- hosts: all   tasks:     - name: get user home directory       shell: >              getent passwd {{ user }}  | awk -F: '{ print $6 }'       changed_when: false       register: user_home      - name: debug output       debug:         var: user_home.stdout 

There may well be a cleaner way of doing this and I'm a little surprised that using become_user to switch to the user specified doesn't seem to affect the env lookup but this should give you what you want.

like image 74
ydaetskcoR Avatar answered Dec 03 '22 21:12

ydaetskcoR


I think there are several answers given here that would work, but I thought I'd show that you can get this from the ansible user module, by registering it as a variable.

- user:     name: www-data     state: present   register: webserver_user_registered 

Note: it will create the user if it doesn't exist...

So we can use debug to show the values of that var, including the path...

- debug:     var: webserver_user_registered  TASK [wordpress : debug] ****************** ok: [wordpresssite.org] => {     "webserver_user_registered": {         "append": false,         "changed": false,         "comment": "www-data",         "failed": false,         "group": 33,         "home": "/var/www",      <<------ this is the user home dir         "move_home": false,         "name": "www-data",         "shell": "/usr/sbin/nologin",         "state": "present",         "uid": 33     } } 

And you can use those properties in other modules like this;

- file:     name: "{{ webserver_user_registered.home }}/.wp-cli"     state: directory 
like image 34
Tom Avatar answered Dec 03 '22 22:12

Tom