Загрузка 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
.