I have an inventory with hosts where some process are running from other users unknown in my inventory.
My ssh key is already copied for the main ansible user as for these other users
I need to build a playbook where I will get the username running some process in one play and in an other play connect to same server with this username and make some changes using ENV of obtained user
For security reasons I can't configure become_user: "{{ process_username }}"
and run my tasks with the same main ansible user as it can't escalate privileges.
This is what I've tried so far:
- name: Get process username with default ansible_user
hosts: all
tasks:
- name: Get process username
shell: ps -eo uname:20,cmd | grep process_name | grep -v grep | head -1 | awk '{print $1}'
register: process_user
- name: Make some changes as process_user.stdout user
hosts: all
remote_user: "{{ hostvars[inventory_hostname].process_user.stdout }}"
tasks:
- name: Make changes
lineinfile:
src: somefile
dst: "{{ansible_env.HOME}}/process_name/somefile"
Unfortunately, ansible fires an error telling me {{ hostvars[inventory_hostname].process_user.stdout }}
is undefined in the second play as my remote_user
.
Any suggestions?
remote_user
is a keyword, not a variable. When used at play level, its content will be evaluated before the actual play starts looping on the hosts. So at that point inventory_hostname
is unset.
You need to either:
remote_user
keyword at task level. This is ok if you only have one or a few tasks in your second play (else you'll have to repeat it many times):
- name: Make some changes
hosts: all
tasks:
- name: Add a line to a file as process_user.stdout user
remote_user: "{{ hostvars[inventory_hostname].process_user.stdout }}"
ansible.builtin.lineinfile:
line: Some line to add
path: "{{ ansible_env.HOME }}/process_name/somefile"
ansible_user
variable instead. This has the same effect but in your specific case, that var will be evaluated every time it is used hence for each task in your play for the corresponding host. This is much more convenient if you have many tasks:
- name: Make some changes as process_user.stdout user
hosts: all
vars:
ansible_user: "{{ hostvars[inventory_hostname].process_user.stdout }}"
tasks:
- name: Add a line to a file
ansible.builtin.lineinfile:
line: Some line to add
path: "{{ ansible_env.HOME }}/process_name/somefile"
- name: Create a new directory
ansible.builtin.file:
path: "{{ ansible_env.HOME }}/process_name/somedir"
state: directory
As pointed out by @U880D in the comments, you can find a good discussion on the difference between the remote_user
keyword and the ansible_user
variable in this other answer