是否可以将 Ansible authorized_key 与多个密钥一起使用?
Is it possible to use Ansible authorized_key exclusive with multiple keys?
我刚开始使用 Ansible,一直在阅读 here 和 google,但还没有找到答案。
我的情况是我在服务器上有 1 个用户,但需要将 2-3 个不同的公钥放入 authorized_keys 文件。
我可以成功删除所有密钥,或使用此脚本添加所有密钥:
---
- 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
它使用 present
标志读取并添加所有键。使用 absent
标志,它会删除列出的所有键。
问题是我有一个仅在服务器上的旧密钥,我想 remove/overwrite 它并为将来的部署覆盖可能在服务器上但不在我的剧本中的任何未经授权的密钥。
使用 exclusive
标志,它只获取最后一个键并添加它。如果它能循环并递归地添加所有键,那就太棒了。如果有办法在 Ansible 中执行此操作,我还没有找到它。
有什么方法可以循环遍历 pub 文件并同时使用 exclusive
选项吗?
有没有办法循环pub文件的同时使用独占选项?
没有。在 docs:
中有关于循环和独占的说明
exclusive: Whether to remove all other non-specified keys from the authorized_keys file. Multiple keys can be specified in a single key string value by separating them by newlines.
This option is not loop aware, so if you use with_ , it will be exclusive per iteration of the loop, if you want multiple keys in the file you need to pass them all to key in a single batch as mentioned above.
因此您需要加入所有密钥并一次发送所有密钥。
像这样:
- name: update SSH keys
authorized_key:
user: <user>
key: "{{ lookup('pipe','cat ../files/pub_keys/*.pub') }}"
state: present
exclusive: yes
在生产 运行 之前检查此代码!
如果您将用户保留在一个变量中,您可以使用这个:
---
- 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
看起来像这样:
---
developers:
- name: user1
publish_ssh_key: ssh-rsa AAAA...
- name: user2
publish_ssh_key: ssh-rsa AAAA...
如果您想避免 pipe
查找(例如,因为路径与角色无关),您还可以结合使用 file
和 fileglob
查找:
- 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
正如我在另一个答案 (Ansible - managing multiple SSH keys for multiple users & roles) 中所写的那样,这是我为我的用例解决此问题的方式。也许它在这里有用?
我将变量中的文件名数组传递给我的 user-account
角色。然后角色获取每个文件的内容,将它们附加到一个以换行符分隔的字符串中,最后将此值设置为新用户的 ssh-key。
.
剧本文件:
- hosts: aws-node1
roles:
- { role: user-account, username: 'developer1', ssh_public_keyfiles: ['peter-sshkey.pub', 'paul-sshkey.pub'] }
.
user-account
的角色定义:
- 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
与前面的答案相同的基本概念,但只使用变量并从 url 中提取密钥,例如 github 或 gitlab。
#Vars
ssh_users:
- user1
- user2
ssh_key_urls: "{{ ssh_users | map('regex_replace', '^(.*)$', 'https://key_server/\1.keys') | list }}"
authorized_keys: "{% for u in ssh_key_urls %}{{ lookup('url', u, split_lines=False) }}\n{% endfor %}"
#task
- name: setup authorized_keys
authorized_key:
key: "{{ authorized_keys }}"
state: present
exclusive: true
我刚开始使用 Ansible,一直在阅读 here 和 google,但还没有找到答案。
我的情况是我在服务器上有 1 个用户,但需要将 2-3 个不同的公钥放入 authorized_keys 文件。
我可以成功删除所有密钥,或使用此脚本添加所有密钥:
---
- 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
它使用 present
标志读取并添加所有键。使用 absent
标志,它会删除列出的所有键。
问题是我有一个仅在服务器上的旧密钥,我想 remove/overwrite 它并为将来的部署覆盖可能在服务器上但不在我的剧本中的任何未经授权的密钥。
使用 exclusive
标志,它只获取最后一个键并添加它。如果它能循环并递归地添加所有键,那就太棒了。如果有办法在 Ansible 中执行此操作,我还没有找到它。
有什么方法可以循环遍历 pub 文件并同时使用 exclusive
选项吗?
有没有办法循环pub文件的同时使用独占选项?
没有。在 docs:
中有关于循环和独占的说明exclusive: Whether to remove all other non-specified keys from the authorized_keys file. Multiple keys can be specified in a single key string value by separating them by newlines. This option is not loop aware, so if you use with_ , it will be exclusive per iteration of the loop, if you want multiple keys in the file you need to pass them all to key in a single batch as mentioned above.
因此您需要加入所有密钥并一次发送所有密钥。
像这样:
- name: update SSH keys
authorized_key:
user: <user>
key: "{{ lookup('pipe','cat ../files/pub_keys/*.pub') }}"
state: present
exclusive: yes
在生产 运行 之前检查此代码!
如果您将用户保留在一个变量中,您可以使用这个:
---
- 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
看起来像这样:
---
developers:
- name: user1
publish_ssh_key: ssh-rsa AAAA...
- name: user2
publish_ssh_key: ssh-rsa AAAA...
如果您想避免 pipe
查找(例如,因为路径与角色无关),您还可以结合使用 file
和 fileglob
查找:
- 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
正如我在另一个答案 (Ansible - managing multiple SSH keys for multiple users & roles) 中所写的那样,这是我为我的用例解决此问题的方式。也许它在这里有用?
我将变量中的文件名数组传递给我的 user-account
角色。然后角色获取每个文件的内容,将它们附加到一个以换行符分隔的字符串中,最后将此值设置为新用户的 ssh-key。
.
剧本文件:
- hosts: aws-node1
roles:
- { role: user-account, username: 'developer1', ssh_public_keyfiles: ['peter-sshkey.pub', 'paul-sshkey.pub'] }
.
user-account
的角色定义:
- 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
与前面的答案相同的基本概念,但只使用变量并从 url 中提取密钥,例如 github 或 gitlab。
#Vars
ssh_users:
- user1
- user2
ssh_key_urls: "{{ ssh_users | map('regex_replace', '^(.*)$', 'https://key_server/\1.keys') | list }}"
authorized_keys: "{% for u in ssh_key_urls %}{{ lookup('url', u, split_lines=False) }}\n{% endfor %}"
#task
- name: setup authorized_keys
authorized_key:
key: "{{ authorized_keys }}"
state: present
exclusive: true