如何从Ansible用户字典生成多行SSH密钥变量以启用exclusive选项
问题场景
现有用户字典结构无法修改,每个用户包含0到多个ssh-keys条目。需要启用ansible.posix.authorized_key的exclusive选项,要求一次性传入该用户所有密钥(多行字符串格式),避免循环执行排他操作导致密钥丢失。
解决方案:完善user_sshkeys变量生成
在ssh_keys.yml中,使用Jinja2循环将用户的ssh-keys转换为符合要求的多行字符串,同时处理无密钥的边界情况:
--- - name: Generate formatted SSH key list ansible.builtin.set_fact: user_sshkeys: |- {% for key_entry in outer_item['ssh-keys'] | default([]) %} {{ key_entry.type }} {{ key_entry.key }} {{ key_entry.comment }} {% endfor %} - name: Apply SSH keys with exclusive mode ansible.posix.authorized_key: user: "{{ outer_item.name }}" key: "{{ user_sshkeys }}" state: present exclusive: true when: outer_item.ensure == 'present' and user_sshkeys | trim != '' - name: Clear authorized_keys for absent users or users with no keys ansible.posix.authorized_key: user: "{{ outer_item.name }}" state: absent exclusive: true when: outer_item.ensure == 'absent' or (outer_item.ensure == 'present' and user_sshkeys | trim == '')
关键细节说明
- 处理无密钥用户:用
default([])确保用户没有ssh-keys字段时不会抛出错误 - 多行字符串格式:
|-标记保证生成的字符串保留换行,同时自动去除最后一行的空行 - 排他模式逻辑:
- 仅当用户状态为
present且存在有效密钥时,执行添加操作并开启exclusive,确保文件中只有指定密钥 - 当用户状态为
absent或用户存在但无密钥时,清空该用户的authorized_keys文件
- 仅当用户状态为
简化写法(可选)
如果偏好过滤器链式调用的简洁风格,也可以这样生成user_sshkeys:
- name: Generate SSH key list via filters ansible.builtin.set_fact: user_sshkeys: "{{ outer_item['ssh-keys'] | default([]) | map('combine') | map('extract', ['type', 'key', 'comment']) | map('join', ' ') | join('\n') }}"
此写法通过map和join直接转换格式,但可读性略低于Jinja2循环方式,按需选择即可。
内容的提问来源于stack exchange,提问作者LeXaNZ
相关产品推荐
相关产品推荐

