如何包括组中所有主机的所有主机密钥

问题描述 投票:0回答:1

[尝试学习Ansible时,我创建了一个实施困难的方案。假设我想使用known_hosts模块将所有SSH主机密钥添加到组中每个成员的/ etc / ssh / ssh_known_hosts文件中。我正在使用2.7,并试图远离with_贬值的循环函数。我可以获得调试中列出的所有键,但是我找不到在模块循环中实现此功能的方法。为了一般地理解该操作,我假设并非所有主机都具有所有类型的密钥,因此它需要是动态的。这是我到目前为止的内容:

- name: SSH Host Keys Debug                                                     
  debug:                                                                        
    msg: "Hostname: {{ hostvars[item].ansible_hostname }},                      
          IP Address: {{ hostvars[item].ansible_eth0.ipv4.address }},           
          Keys: {{ hostvars[item] | select('match', '^ansible_ssh_host_key_.+_public') | map('extract', hostvars[item]) | list }}"
  loop: "{{ groups['haproxy'] }}" 

然后创建一个循环函数,根据其拥有的键数,每个主机对该模块多次调用该模块。

- name: SSH Host Keys                                                           
  become: true                                                                  
  known_hosts:                                                                  
    dest: /etc/ssh/ssh_known_hosts                                              
    name: "{{ item.ansible_hostname }}"                                         
    key: "{{ item.ansible_hostname }},{{ item.ansible_eth0.ipv4.address }} {{ item.<public_key> }}"
  loop: <nested loop that provides hostname, ipv4_address and public_keys>

事实包括这个有趣的部分:

...
        "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDhGYjJS18MSCojIDLA9MTxITHpy+IOBFCHR+ZSZMyr5ek0r4RCK+zo6D1WZNs0dWcUB7IUJMThKcPpxdbrC0rk=",
        "ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIBZjI7AJ5SHU31V6Vs9WTxLss/5gU/3pJJlTTzpJxcyr",                                                                                                                                                         
        "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDH3OunSMQfaksqVxlLhKUyDUegaw6QuOiemgBWwwJypiDRshF0N2xQ6/RqHYA/gY+oDieIHzbs6OtxNt7JbSOwkjnKrYBkqzVQqtCtjpJ+pbzAcxdYwjfEYNlV/Fq41XrsFaWQgbQB57yS3dJVneheXskSc/mIwX3a2143X1CFLSz9krhwcNIWaAhZFMlV0ZqRSvH
DoiDZ4rQ4qQ4riaTm/NXjJzJjQqSiwUZUQdBtv88Ik1trQJUwKsYq2WZKiuv6yp/XVLL1/LLYQQJeH2GRqy8EI1TYRunrfHEo/D3T5QPsaJ1up/YNPtRP+H3dA68Ybwowb8m5A9IoAtHbHdEr",
...

调试的输出是:

TASK [base_conf : SSH Host Keys Debug] ************************************************************************************************
task path: /home/rleblanc/code/ansible_learn/base_conf/tasks/main.yml:30
ok: [ansible-a] => (item=ansible-a) => {
    "msg": "Hostname: ansible-a, IP Address: 192.168.99.48, Keys: ['AAAAB3NzaC1yc2EAAAADAQABAAABAQDH3OunSMQfaksqVxlLhKUyDUegaw6QuOiemgBWwwJypiDRshF0N2xQ6/RqHYA/gY+oDieIHzbs6OtxNt7JbSOwkjnKrYBkqzVQqtCtjpJ+pbzAcxdYwjfEYNlV/Fq41XrsFaWQgbQB57yS3dJVneheXskSc/mIwX3a2143X1CFLSz9krhwcNIWaAhZFMlV0ZqRSvHDoiDZ4rQ4qQ4riaTm/NXjJzJjQqSiwUZUQdBtv88Ik1trQJUwKsYq2WZKiuv6yp/XVLL1/LLYQQJeH2GRqy8EI1TYRunrfHEo/D3T5QPsaJ1up/YNPtRP+H3dA68Ybwowb8m5A9IoAtHbHdEr', 'AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDhGYjJS18MSCojIDLA9MTxITHpy+IOBFCHR+ZSZMyr5ek0r4RCK+zo6D1WZNs0dWcUB7IUJMThKcPpxdbrC0rk=', 'AAAAC3NzaC1lZDI1NTE5AAAAIBZjI7AJ5SHU31V6Vs9WTxLss/5gU/3pJJlTTzpJxcyr']"
}

编辑1

一些完成每个主机所需的伪代码:

for host in groups['haproxy']:
   for key in host.ansible_ssh_host_key_*_public:
     <pass key to known_host module>
ansible
1个回答
0
投票

Ansible在嵌套循环中并不是很出色。我们可以解决这个问题,但这有点难看。 ecdsa公钥使我们的生活变得复杂,因为尽管大多数密钥的类型在公钥文件中指定为ssh-<type>,但对于ecdsa密钥,显然是ecdsa-sha2-nistp256

这是我想出的:

---
- hosts: all
  tasks:

    # In this first task, we construct for each host in the `all` group
    # a list of dictionaries that contain information about the ssh
    # hostkeys, extracted from the `ansible_ssh_host_key_*` variables.
    #
    # We are looping over all variables (and values) for this host for which
    # the variable name starts with `ansible_ssh_host_key`.
    - set_fact:
        hostkeys: >-
          {{ (hostkeys|default([])) + [{
            'hostname': inventory_hostname,
            'type': item.key|regex_replace('ansible_ssh_host_key_([^_]+)_public', '\1'),
            'key': item.value
          }] }}
      loop: >-
        {{ hostvars[inventory_hostname]|
           dict2items|
           selectattr('key', 'match', '^ansible_ssh_host_key_')|list }}

- hosts: localhost
  gather_facts: false
  tasks:

    # Now we take those per-host lists and construct one combined list
    # with all the information.
    - set_fact:
        hostkeys: "{{ (hostkeys|default([])) + hostvars[item].hostkeys }}"
      loop: "{{ groups.all }}"

- hosts: all
  gather_facts: false
  tasks:

    # Finally, on each host, we write a known_hosts file containing all the
    # host keys. I'm using an alternate path here because I didn't want
    # to actually write to /etc/ssh/known_hosts on my system.
    - known_hosts:
        path: "/tmp/hosts-{{ inventory_hostname }}"
        name: "{{ item.hostname }}"
        key: "{{ item.hostname }} {{ keytype }} {{ item.key }}"
      vars:
        keytype: >-
          {{ (item.type == 'ecdsa')|
             ternary('ecdsa-sha2-nistp256', 'ssh-' ~ item.type) }}
      loop: "{{ hostvars.localhost.hostkeys }}"
      loop_control:
        label: "{{ item.hostname }} {{ keytype }} {{ item.key[:20] }}..."

我没有在这里打扰ip地址,但是添加起来应该不会太困难(将信息包括在第一步中生成的hostkeys字典中,然后将其用于known_hosts模块的参数中) )。

© www.soinside.com 2019 - 2024. All rights reserved.