You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

错误原因

  1. 变量误用:ansible_user_id代表Ansible连接目标机器时使用的初始用户,不会因become切换用户而更新。切换后的用户需要用ansible_become_user变量获取。
  2. 重复设置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 14:48:26