Ansible多用户执行角色问题:sudo切换用户后变量取值错误
Ansible切换用户后Role变量获取错误问题排查与修复
问题场景
尝试在多台机器上为多个用户执行Ansible角色,编写的Playbook和Role代码如下,但Role中始终获取到执行用户ansibleadm,而非切换后的目标用户(wasadm/ihsadm)。
原Playbook代码
- name: Install dotfiles across hosts hosts: was gather_facts: true become: true become_user: "{{ item }}" vars: users: - wasadm - ihsadm tasks: - name: Execute role as specific user ansible.builtin.include_role: name: installProfile apply: become: true become_user: "{{ item }}" loop: "{{ users }}"
原Role的tasks/main.yml代码
#====== ANSIBLE ============================================================ # NAME: tasks/main.yml # DESCRIPTION: Primary entry point for this play #============================================================================= --- - name: Remove dotfiles pull ansible.builtin.file: path: /home/{{ ansible_user_id }}/.dotfiles state: absent - name: Extract dotfiles zip ansible.builtin.unarchive: src: /var/tmp/dotfiles.zip dest: /home/{{ ansible_user_id }} owner: "{{ ansible_user_id }}" notify: - executeInstallation - name: Remove dotfiles archive ansible.builtin.file: path: /var/tmp/dotfiles.zip state: absent
错误原因
- 变量误用:
ansible_user_id代表Ansible连接目标机器时使用的初始用户,不会因become切换用户而更新。切换后的用户需要用ansible_become_user变量获取。 - 重复设置Become:Play级别已经设置
become_user: "{{ item }}",又在include_role的apply中重复设置,导致上下文混乱,影响变量的正确传递。
修复方案
方案1:使用ansible_become_user变量替换ansible_user_id
保留循环逻辑,去掉重复的apply设置,修改Role中的变量:
修正后的Playbook
- name: Install dotfiles across hosts hosts: was gather_facts: true vars: users: - wasadm - ihsadm tasks: - name: Execute role as specific user ansible.builtin.include_role: name: installProfile loop: "{{ users }}" become: true become_user: "{{ item }}"
修正后的Role tasks/main.yml
#====== ANSIBLE ============================================================ # NAME: tasks/main.yml # DESCRIPTION: Primary entry point for this play #============================================================================= --- - name: Remove dotfiles pull ansible.builtin.file: path: /home/{{ ansible_become_user }}/.dotfiles state: absent - name: Extract dotfiles zip ansible.builtin.unarchive: src: /var/tmp/dotfiles.zip dest: /home/{{ ansible_become_user }} owner: "{{ ansible_become_user }}" notify: - executeInstallation - name: Remove dotfiles archive ansible.builtin.file: path: /var/tmp/dotfiles.zip state: absent
方案2:直接传递循环变量到Role
通过显式传递变量,提升代码可读性,适合复杂场景:
修正后的Playbook
- name: Install dotfiles across hosts hosts: was gather_facts: true vars: users: - wasadm - ihsadm tasks: - name: Execute role as specific user ansible.builtin.include_role: name: installProfile vars: target_user: "{{ item }}" loop: "{{ users }}" become: true become_user: "{{ item }}"
修正后的Role tasks/main.yml
#====== ANSIBLE ============================================================ # NAME: tasks/main.yml # DESCRIPTION: Primary entry point for this play #============================================================================= --- - name: Remove dotfiles pull ansible.builtin.file: path: /home/{{ target_user }}/.dotfiles state: absent - name: Extract dotfiles zip ansible.builtin.unarchive: src: /var/tmp/dotfiles.zip dest: /home/{{ target_user }} owner: "{{ target_user }}" notify: - executeInstallation - name: Remove dotfiles archive ansible.builtin.file: path: /var/tmp/dotfiles.zip state: absent
说明
- 方案1利用Ansible内置变量
ansible_become_user直接获取切换后的用户,无需额外传参。 - 方案2通过显式传递变量,逻辑更清晰,便于后续维护。
内容的提问来源于stack exchange,提问作者user4654707
相关产品推荐
相关产品推荐

