it-swarm.com.ru

как определить закрытый ключ ssh для серверов, извлекаемых при динамическом учете в файлах

Я столкнулся с одной проблемой конфигурации при кодировании ANSIBLE playbook для файла закрытого ключа ssh.

Как мы знаем, мы можем определить комбинацию с хост-сервером, ip и связанным с ним закрытым ключом ssh в файле ansible hosts для статических серверов инвентаризации.

Но я понятия не имею, как определить это с динамическими серверами инвентаризации.

Пример:

---
- hosts: tag_Name_server1
  gather_facts: no
  roles:
    - role1

- hosts: tag_Name_server2
  gather_facts: no
  roles:
    - roles2

Ниже приведена команда для вызова этой пьесы:

ansible-playbook test.yml -i ec2.py --private-key ~/.ssh/SSHKEY.pem

Мой вопрос:

  1. Как я могу определить ~/.ssh/SSHKEY.pem в ANSIBLE файлах, а не в командной строке
  2. Я предполагаю, что в playbook может быть один параметр, такой как "collect_facts", чтобы определить, какой закрытый ключ следует использовать для указанных выше хостов, но похоже, что такого параметра нет?
  3. Если нет способа определить закрытый ключ в файлах, что следует определить в командной строке, если для разных серверов динамической выборки для одной книги воспроизведения будет использоваться другой файл ключа?

Спасибо за ваши комментарии

50
Clark Zheng

TL; DR: укажите файл ключа в файле групповой переменной, поскольку 'tag_Name_server1' является группой.


Примечание: я предполагаю, что вы используете скрипт внешней инвентаризации EC2 . Если вы используете какой-то другой метод динамической инвентаризации, вам может понадобиться настроить это решение.

Это проблема, с которой я боролся, в течение нескольких месяцев, и, наконец, я нашел решение, благодаря предложению Брайана Кока здесь . Хитрость заключается в том, чтобы использовать механизмы групповых переменных Ansible для автоматической передачи правильного файла ключей SSH для машины, с которой вы работаете.

Сценарий инвентаризации EC2 автоматически устанавливает различные группы, которые вы можете использовать для обращения к хостам. Вы используете это в своей книге игр: в первой игре вы говорите Ansible применить 'role1' ко всей группе tag_Name_server1. Мы хотим, чтобы Ansible использовал определенный ключ SSH для любого хоста в группе "tag_Name_server1", в которую входят файлы групповых переменных.

Предполагая, что ваша книга воспроизведения находится в каталоге "my-playbooks", создайте файлы для каждой группы в каталоге "group_vars":

my-playbooks
|-- test.yml
+-- group_vars
     |-- tag_Name_server1.yml
     +-- tag_Name_server2.yml

Теперь, каждый раз, когда вы обращаетесь к этим группам в книге игр, Ansible проверит соответствующие файлы и загрузит все переменные, которые вы там определили.

В каждом файле группы var мы можем указать файл ключа, который будет использоваться для подключения к хостам в группе:

# tag_Name_server1.yml
# --------------------
# 
# Variables for EC2 instances named "server1"
---
ansible_ssh_private_key_file: /path/to/ssh/key/server1.pem

Теперь, когда вы запускаете свою игровую книгу, она должна автоматически подбирать нужные клавиши!


Использование переменных среды для переносимости

Я часто запускаю playbooks на разных серверах (локальный, удаленный сервер сборки и т.д.), Поэтому мне нравится параметризовывать вещи. Вместо того, чтобы использовать фиксированный путь, у меня есть переменная окружения с именем SSH_KEYDIR, которая указывает на каталог, где хранятся ключи SSH.

В этом случае файлы моей группы vars выглядят так:

# tag_Name_server1.yml
# --------------------
# 
# Variables for EC2 instances named "server1"
---
ansible_ssh_private_key_file: "{{ lookup('env','SSH_KEYDIR') }}/server1.pem"

Дальнейшие улучшения

Вероятно, есть куча хороших способов улучшить это. Во-первых, вам все равно нужно вручную указать, какой ключ использовать для каждой группы. Поскольку сценарий инвентаризации EC2 содержит сведения о паре ключей, используемой для каждого сервера, возможно, существует способ получить имя ключа непосредственно из самого сценария. В этом случае вы можете указать каталог, в котором находятся ключи (как указано выше), и попросить его выбрать правильные ключи на основе данных инвентаризации.

48
Tiro

Лучшее решение, которое я мог бы найти для этой проблемы, это указать файл закрытого ключа в ansible.cfg (я обычно храню его в той же папке, что и книга воспроизведения):

[defaults]
inventory=ec2.py
vault_password_file = ~/.vault_pass.txt
Host_key_checking = False
private_key_file = /Users/eric/.ssh/secret_key_rsa

Тем не менее, он все еще устанавливает глобальный закрытый ключ для всех хостов в playbook.

Примечание: вы должны указать полный путь к файлу ключа - ~ user/.ssh/some_key_rsa игнорируется.

23
tchu

Вы можете просто определить ключ для использования непосредственно при запуске команды:

ansible-playbook \
        \ # Super verbose output incl. SSH-Details:
    -vvvv \
        \ # The Server to target: (Keep the trailing comma!)
    -i "000.000.0.000," \
        \ # Define the key to use:
    --private-key=~/.ssh/id_rsa_ansible \
        \ # The `env` var is needed if `python` is not available:
    -e 'ansible_python_interpreter=/usr/bin/python3' \ # Needed if `python` is not available
        \ # Dry–Run:
    --check \
    deploy.yml

Копировать вставить:

ansible-playbook -vvvv --private-key=/Users/you/.ssh/your_key deploy.yml
13
kaiser

Я использую следующую конфигурацию:

#site.yml:
- name: Example play
  hosts: all
  remote_user: ansible
  become: yes
  become_method: Sudo
  vars:
    ansible_ssh_private_key_file: "/home/ansible/.ssh/id_rsa"
4
Kenuat

У меня была похожая проблема, и я решил ее с помощью патча к ec2.py и добавления некоторых параметров конфигурации к ec2.ini. Патч принимает значение ec2_key_name, префиксирует его с помощью ssh_key_path, добавляет ssh_key_suffix в конец и записывает ansible_ssh_private_key_file в качестве этого значения.

Следующие переменные должны быть добавлены в ec2.ini в новом разделе 'ssh' (это необязательно, если значения по умолчанию соответствуют вашей среде):

[ssh]
# Set the path and suffix for the ssh keys
ssh_key_path = ~/.ssh
ssh_key_suffix = .pem

Вот патч для ec2.py:

204a205,206
>     'ssh_key_path': '~/.ssh',
>     'ssh_key_suffix': '.pem',
422a425,428
>         # SSH key setup
>         self.ssh_key_path = os.path.expanduser(config.get('ssh', 'ssh_key_path'))
>         self.ssh_key_suffix = config.get('ssh', 'ssh_key_suffix')
> 
1490a1497
>         instance_vars["ansible_ssh_private_key_file"] = os.path.join(self.ssh_key_path, instance_vars["ec2_key_name"] + self.ssh_key_suffix)
3
Daz