Ubuntu 是否可以将Ansible授权密钥与多个密钥一起使用?

Ubuntu 是否可以将Ansible授权密钥与多个密钥一起使用?,ubuntu,ansible,ansible-playbook,authorized-keys,Ubuntu,Ansible,Ansible Playbook,Authorized Keys,我对Ansible的使用还相当陌生,一直在阅读和谷歌,还没有找到答案 我的场景是,服务器上有1个用户,但需要将2-3个不同的发布密钥放入其授权密钥文件中 我可以使用此脚本成功删除所有密钥或添加所有密钥: --- - hosts: all tasks: - name: update SSH keys authorized_key: user: <user> key: "{{ lookup('file', item) }}" state:

我对Ansible的使用还相当陌生,一直在阅读和谷歌,还没有找到答案

我的场景是,服务器上有1个用户,但需要将2-3个不同的发布密钥放入其授权密钥文件中

我可以使用此脚本成功删除所有密钥或添加所有密钥:

---
  - hosts: all

 tasks:
  - name: update SSH keys
    authorized_key:
     user: <user>
     key: "{{ lookup('file', item) }}"
     state: present
     #exclusive: yes
    with_fileglob:
      - ../files/pub_keys/*.pub
---
-主持人:全部
任务:
-名称:更新SSH密钥
授权密钥:
用户:
键:“{lookup('file',item)}”
国家:现在
#独家:是的
使用_fileglob:
-../files/pub_keys/*.pub
使用
present
标志读取并添加所有键。使用
缺席
标志,它将删除列出的所有键

问题是,我有一个旧密钥,它只在服务器上,我想删除/覆盖它,并为将来的部署覆盖任何未经授权的密钥,这些密钥可能在服务器上,而不是在我的playbook中

使用
exclusive
标志,它只接受最后一个键并将其添加。这将是美妙的,如果它将循环和重复添加所有的关键点。如果在Ansible中有这样做的方法,我还没有找到

是否有任何方法可以在pub文件上循环,同时使用
exclusive
选项

是否有办法循环发布文件,同时使用独占选项

否。在以下内容中有一个关于循环和独占的注释:

独占:是否从授权密钥文件中删除所有其他非指定密钥。通过使用换行符分隔多个键,可以在单个键字符串值中指定多个键。 此选项不支持循环,因此,如果与u一起使用,则循环的每次迭代都将是独占的,如果您希望文件中有多个密钥,则需要将它们全部传递给上述单个批中的密钥

因此,您需要加入所有密钥并立即发送所有密钥。
大概是这样的:

- name: update SSH keys
  authorized_key:
    user: <user>
    key: "{{ lookup('pipe','cat ../files/pub_keys/*.pub') }}"
    state: present
    exclusive: yes
---

developers:
  - name: user1
    publish_ssh_key: ssh-rsa AAAA...
  - name: user2
    publish_ssh_key: ssh-rsa AAAA...
-名称:更新SSH密钥
授权密钥:
用户:
键:{{lookup('pipe','cat../files/pub_keys/*.pub')}
国家:现在
独家:是的

在投入生产前检查此代码

如果将用户保留在变量中,则可以使用以下方法:

---

- hosts: all
  vars_files:
    - roles/users/vars/main.yml
  tasks:
    - name: Allow other users to login to the account
      authorized_key:
        user: user_name
        exclusive: yes
        key: "{{ developers|map(attribute='publish_ssh_key')|join('\n') }}"
roles/users/vars/main.yml
如下所示:

- name: update SSH keys
  authorized_key:
    user: <user>
    key: "{{ lookup('pipe','cat ../files/pub_keys/*.pub') }}"
    state: present
    exclusive: yes
---

developers:
  - name: user1
    publish_ssh_key: ssh-rsa AAAA...
  - name: user2
    publish_ssh_key: ssh-rsa AAAA...

如果您希望避免
管道
查找(例如,因为路径与角色无关),还可以结合使用
文件
文件全局
查找:

- name: update SSH keys
  authorized_key:
    user: <user>
    key:  "{% for key in lookup('fileglob', 'pub_keys/*.pub').split(',') %}{{ lookup('file', key) ~ '\n'}}{% endfor %}"
    state: present
    exclusive: yes
-名称:更新SSH密钥
授权密钥:
用户:
键:“{%用于查找中的键('fileglob','pub_-keys/*.pub').split(',')%}{{lookup('file',key)~'\n'}}{%endfor%}”
国家:现在
独家:是的

正如我在另一个答案()中所写的,这就是我为我的用例解决这个问题的方法。也许它在这里有用

我将变量中的文件名数组传递给我的
用户帐户
角色。然后,角色获取每个文件的内容,将它们附加到一个换行分隔的字符串中,最后将该值设置为新用户的ssh密钥

剧本文件:

- hosts: aws-node1
  roles:
    - { role: user-account, username: 'developer1', ssh_public_keyfiles: ['peter-sshkey.pub', 'paul-sshkey.pub'] }

用户帐户的角色定义

- name: add user
  user:
    name: "{{username}}"


- name: lookup ssh pubkeys from keyfiles and create ssh_pubkeys_list
  set_fact:
    ssh_pubkeys_list: "{{ lookup('file', item) }}"
  with_items:
    "{{ssh_public_keyfiles}}"
  register: ssh_pubkeys_results_list


- name: iterate over ssh_pubkeys_list and join into a string
  set_fact:
    ssh_pubkeys_string: "{{ ssh_pubkeys_results_list.results | map(attribute='ansible_facts.ssh_pubkeys_list') | list | join('\n') }}"


- name: update SSH authorized_keys for user {{ username }} with contents of ssh_pubkeys_string
  authorized_key:
    user: "{{ username }}"
    key: "{{ ssh_pubkeys_string }}"
    state: present
    exclusive: yes

哦,老兄,你真是救命恩人!很好!我刚刚发现了
lookup
的东西,但我试图理解它。非常感谢你!您需要小心,并将EOL放在每个发布密钥文件的末尾。否则,键可能会连在一行中。这只会添加最后一个键,但根据文档,它应该可以工作“通过使用换行符分隔,可以在单个键字符串值中指定多个键”你知道它为什么会断开吗?@goetzc我不知道:-(嘿,这是因为我有相同的测试键,只是注释不同,然后Ansible只添加了最后一个:)使用“查询”比使用“查找”更好-这样你就不需要“拆分”并得到不存在路径的保护:
key:{%对于查询中的键('fileglob','pub_key/*')%}{{{查找('file',key)~'\n'}}{%endfor%}“