Загрузка SSH-ключей с помощью Ansible
При развёртывании систем бывает нужно сгенерировать SSH-ключи, которые будут использовать удалённые серверы для доступа друг к другу. Например, родительский сервер head должен иметь доступ по SSH к нескольким дочерним серверам node*. Ниже приведён пример плейбука для Ansible, который добавляет на сервер head новый SSH-ключ и размещает его публичную часть на серверы node*. Т.е. после его выполнения родительский сервер будет иметь доступ по SSH к дочерним.
Плейбук является идемпотентным, т.е. при повторном выполнении он проверяет, что ключ уже сгенерирован и размещен на серверах. Но если ключ или запись в known_hosts будут удалены, то он их восстановит.
Плейбук deploy-ssh-key.yml:
| |
- <1> Первый play: на главном хосте создаём SSH-ключ и добавляем в
known_hostsвсе дочерние хосты. - <4> Генерируем ed25519 SSH-ключ.
- <12> Записываем публичную часть ключа в переменную.
- <16> Добавляем все дочерние хосты в
known_hosts. - <26> Второй play: на каждом дочернем хосте заносим главный хост в список авторизованных ключей.
Файл add-known-host.yml:
| |
- <1> Генерируем запись для
known_hosts. - <5> Заносим родительский хост в
known_hosts.
Примечания
Запись дочерних хостов вынесена в отдельный файл, т.к. в Ansible нельзя создавать цикл по нескольким переменным для блоков (а у нас 2 задачи - генерация записи через
ssh-keyscanи запись вknown_hosts). Если дочерний хост только один, то можно объединить всё в один плейбук.Для доступа к переменной
public_ssh_keyиспользуетсяhostvars['head'], т.к. переменные хранятся на уровне хоста. Чтобы не привязываться к имени конкретного хоста, можно завести dummy-хост, в котором будут храниться общие переменные для всего плейбука. Например:1 2 3 4- name: Add dummy host with variable ansible.builtin.add_host: name: dummy-host public_ssh_key: "{{ key_result.public_key }}"Можно не добавлять родительский хост в
known_hostsдочерних, тогда нужно будет при работе по SSH использовать атрибутStrictHostKeyChecking=no.