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

Ansible执行角色遇用户不存在报错:多服务器多用户SSH密钥管理解决方法

解决Ansible authorized_key模块用户不存在时报错的问题

我明白你遇到的困扰了——当目标服务器上没有对应的用户时,authorized_key模块会因为找不到用户而抛出getpwnam(): name not found的错误。这是因为这个模块本身依赖系统中存在指定用户,执行操作前会先验证用户的存在性。结合你多服务器多用户SSH密钥管理的需求,咱们可以通过以下步骤解决:

问题根源

authorized_key模块在处理密钥前,会调用系统函数检查用户是否存在,所以如果用户还未创建(或已被删除),直接操作密钥就会触发这个错误。另外我注意到你的变量里path字段有拼写错误:authoried_keys应该是authorized_keys,这个小细节也得修正,不然后续即使用户存在,也会找不到密钥文件路径。

解决方案

我们需要先确保用户的状态符合要求(存在/不存在),再去管理SSH密钥。具体分两步执行:

1. 先管理用户的存在状态

添加一个user模块的任务,遍历你的user_list,根据每个用户的state参数创建或删除用户。对于present状态的用户,顺便创建好.ssh目录并设置正确权限(避免后续密钥写入时出现权限问题)。

2. 再执行SSH密钥管理任务

此时用户状态已经符合要求,执行authorized_key模块就不会再出现用户找不到的错误了。对于state: absent的用户,我们可以加上条件判断,只有当用户存在时才去删除密钥(或者直接执行,authorized_key处理absent状态时用户不存在通常不会报错,但加判断更稳妥)。

修改后的完整Playbook

vars:
  user_list:
    - user: test1
      state: present
      path: /usr/local/test1/.ssh/authorized_keys  # 修正拼写错误
      keys:
        - "ssh-rsa test1"
    - user: test2
      state: absent
      path: /home/test2/.ssh/authorized_keys  # 修正拼写错误
      keys:
        - "ssh-rsa test2"

tasks:
  - name: Manage user accounts
    user:
      name: "{{ item.user }}"
      state: "{{ item.state }}"
      home: "{{ item.path | dirname | dirname }}"  # 从密钥路径中提取家目录
      create_home: yes  # 状态为present时自动创建家目录
    loop: "{{ user_list }}"
    register: user_result

  - name: Create .ssh directory for present users
    file:
      path: "{{ item.path | dirname }}"
      state: directory
      owner: "{{ item.user }}"
      group: "{{ item.user }}"
      mode: '0700'
    loop: "{{ user_list }}"
    when: item.state == 'present'

  - name: Manage SSH-keys
    authorized_key:
      user: "{{ item.0.user }}"
      key: "{{ item.1 }}"
      path: "{{ item.0.path }}"
      state: "{{ item.0.state }}"
    with_subelements:
      - '{{ user_list }}'
      - keys
    when: >
      (item.0.state == 'present' and user_result.results | selectattr('item.user', 'equalto', item.0.user) | map(attribute='changed') | first)
      or (item.0.state == 'absent' and user_result.results | selectattr('item.user', 'equalto', item.0.user) | map(attribute='failed') | first == false)

代码说明

  • 用户管理任务:用user模块处理用户的创建/删除,通过home参数从密钥路径中提取家目录(比如/usr/local/test1/.ssh/authorized_keys的家目录是/usr/local/test1),create_home: yes确保创建用户时自动生成家目录。
  • .ssh目录创建:对于需要保留的用户,提前创建.ssh目录并设置严格的0700权限,这是SSH密钥目录的标准权限要求。
  • 密钥管理任务的条件判断:
    • 对于present状态的用户,只有当用户被成功创建(或已存在)时才执行密钥添加;
    • 对于absent状态的用户,只有当用户存在(删除操作未失败)时才执行密钥删除,避免不必要的错误。

这样调整后,就能完美解决用户不存在时的报错问题,同时修正了路径拼写错误,确保密钥管理的正确性。

内容的提问来源于stack exchange,提问作者omfo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:32:24