Ansible中如何筛选存在用户并执行SSH授权密钥配置任务
解决Ansible中仅为存在用户配置SSH授权密钥的问题
核心需求
基于username:publickey格式的变量列表,完成:
- 验证目标系统中对应用户已存在
- 仅对存在的用户,确保
/home/$user/.ssh/authorized_keys文件及路径权限正确
现有变量定义
ssh_vars: auth_keys: bob: "bobs_public_key_string" anne: "annes_public_key_string" anon: "anons_public_key_string"
问题分析
原遍历方式loop: "{{ ssh_vars.auth_keys }}"仅能获取公钥值,无法直接拿到用户名;且判断用户存在的逻辑不够精准,需要更可靠的判断方式。
解决方案
1. 修正遍历方式,获取键值对
使用dict2items过滤器将字典转换为包含key(用户名)和value(公钥)的列表,遍历过程中可同时获取用户名和对应公钥:
- name: 遍历auth_keys并为存在的用户执行SSH配置任务 ansible.builtin.include_tasks: "ssh_dirs.yaml" loop: "{{ ssh_vars.auth_keys | dict2items }}" loop_control: loop_var: user_key_pair
2. 在子任务中精准判断用户是否存在
修改ssh_dirs.yaml,通过getent模块查询后,直接检查getent_passwd中对应用户是否不为null,这是最可靠的判断方式:
- name: 查询目标系统用户信息 ansible.builtin.getent: database: passwd key: "{{ user_key_pair.key }}" fail_key: false register: userlookup - name: 仅当用户存在时配置SSH目录及密钥 block: - name: 创建用户.ssh目录(若不存在) ansible.builtin.file: path: "/home/{{ user_key_pair.key }}/.ssh" state: directory owner: "{{ user_key_pair.key }}" group: "{{ user_key_pair.key }}" mode: '0700' - name: 配置authorized_keys文件 ansible.builtin.lineinfile: path: "/home/{{ user_key_pair.key }}/.ssh/authorized_keys" line: "{{ user_key_pair.value }}" state: present owner: "{{ user_key_pair.key }}" group: "{{ user_key_pair.key }}" mode: '0600' when: userlookup.ansible_facts.getent_passwd[user_key_pair.key] is not none
3. 可选:提前筛选存在的用户列表(优化性能)
如果目标主机用户数量不多,可先一次性获取所有系统用户,提前筛选出变量中存在的用户,再遍历执行任务:
- name: 获取所有系统用户 ansible.builtin.getent: database: passwd - name: 筛选出变量中存在的系统用户 set_fact: existing_users_with_keys: "{{ ssh_vars.auth_keys | dict2items | selectattr('key', 'in', getent_passwd.keys()) | list }}" - name: 为存在的用户执行SSH配置任务 ansible.builtin.include_tasks: "ssh_dirs.yaml" loop: "{{ existing_users_with_keys }}" loop_control: loop_var: user_key_pair
此时ssh_dirs.yaml中可省略用户存在的判断,直接执行配置任务即可。
关键判断逻辑说明
判断用户存在的精准方式是检查getent_passwd中对应用户的条目是否不为null,即:
when: userlookup.ansible_facts.getent_passwd[user_key_pair.key] is not none
这种方式比检查msg是否存在更可靠,因为用户不存在时getent_passwd中对应用户的值会明确为null,而非依赖msg字段的有无。
内容的提问来源于stack exchange,提问作者another_d
相关产品推荐
相关产品推荐

