it-swarm.com.de

Definieren des privaten SSH-Schlüssels für Server, die durch dynamisches Inventar in Dateien abgerufen werden

Ich habe ein Konfigurationsproblem beim Codieren eines nicht lesbaren Playbooks für eine SSH-Datei mit privatem Schlüssel festgestellt.

Wie wir wissen, können wir die Kombination mit Hostserver, IP und zugehörigem SSH-privaten Schlüssel in einer Ansible-Hosts-Datei für statische Inventarserver definieren.

Aber ich habe keine Ahnung, wie man das mit dynamischen Inventarservern definiert.

Ex:

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

- hosts: tag_Name_server2
  gather_facts: no
  roles:
    - roles2

Der folgende Befehl wird verwendet, um das Playbook aufzurufen:

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

Meine Frage ist:

  1. Wie kann ich ~/.ssh/SSHKEY.pem in ansible Dateien anstatt in der Befehlszeile definieren
  2. Ich vermute, es gibt einen Parameter im Playbook wie "gather_facts", mit dem festgelegt werden kann, welcher private Schlüssel für die oben genannten Hosts verwendet werden soll, aber es scheint, als gäbe es keinen solchen Parameter?
  3. Wenn es keine Möglichkeit gibt, einen privaten Schlüssel in Dateien zu definieren, was sollte in der Befehlszeile definiert werden, wenn unterschiedliche Schlüsseldateien für unterschiedliche dynamisch abgerufene Server für ein Wiedergabebuch verwendet werden?

Vielen Dank für Ihre Kommentare

50
Clark Zheng

TL; DR: Geben Sie die Schlüsseldatei in der Gruppenvariablendatei an, da 'tag_Name_server1' eine Gruppe ist.


Hinweis: Ich gehe davon aus, dass Sie das EC2-Skript für externes Inventar verwenden. Wenn Sie einen anderen Ansatz für dynamisches Inventar verwenden, müssen Sie möglicherweise diese Lösung optimieren.

Dies ist ein Problem, mit dem ich seit Monaten immer wieder zu kämpfen habe, und dank Brian Cocas Vorschlag habe ich endlich eine Lösung gefunden hier . Der Trick besteht darin, die Gruppenvariablenmechanismen von Ansible zu verwenden, um automatisch die richtige SSH-Schlüsseldatei für den Computer weiterzuleiten, mit dem Sie arbeiten.

Das EC2-Inventarskript richtet automatisch verschiedene Gruppen ein, mit denen Sie auf Hosts verweisen können. Sie verwenden dies in Ihrem Playbook: Im ersten Spiel weisen Sie Ansible an, 'role1' auf die gesamte 'tag_Name_server1'-Gruppe anzuwenden. Wir möchten Ansible anweisen, einen bestimmten SSH-Schlüssel für einen beliebigen Host in der Gruppe 'tag_Name_server1' zu verwenden, in der Gruppenvariablendateien eingehen.

Angenommen, Ihr Playbook befindet sich im Verzeichnis "my-playbooks". Erstellen Sie Dateien für jede Gruppe im Verzeichnis "group_vars":

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

Jedes Mal, wenn Sie in einem Playbook auf diese Gruppen verweisen, überprüft Ansible die entsprechenden Dateien und lädt alle Variablen, die Sie dort definiert haben.

In jeder Gruppen-Var-Datei können wir die Schlüsseldatei angeben, die für die Verbindung zu Hosts in der Gruppe verwendet werden soll:

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

Wenn Sie jetzt Ihr Playbook ausführen, sollte es automatisch die richtigen Schlüssel aufheben!


Verwenden von Umgebungsvariablen für die Portabilität

Ich führe oft Playbooks auf vielen verschiedenen Servern aus (lokaler, Remote Build Server usw.), deshalb parametriere ich gerne Dinge. Anstatt einen festen Pfad zu verwenden, habe ich eine Umgebungsvariable namens SSH_KEYDIR, die auf das Verzeichnis verweist, in dem die SSH-Schlüssel gespeichert sind.

In diesem Fall sehen meine Gruppen-VAR-Dateien stattdessen folgendermaßen aus:

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

Weitere Verbesserungen

Es gibt wahrscheinlich ein paar nette Möglichkeiten, wie dies verbessert werden könnte. Zum einen müssen Sie immer noch manuell angeben, welcher Schlüssel für jede Gruppe verwendet werden soll. Da das EC2-Inventarskript Details zu dem für jeden Server verwendeten Schlüsselpaar enthält, gibt es wahrscheinlich eine Möglichkeit, den Schlüsselnamen direkt aus dem Skript selbst abzurufen. In diesem Fall können Sie das Verzeichnis angeben, in dem sich die Schlüssel befinden (wie oben), und die richtigen Schlüssel anhand der Inventardaten auswählen.

48
Tiro

Die beste Lösung für dieses Problem ist die Angabe einer privaten Schlüsseldatei in der Datei ansible.cfg (ich behalte sie normalerweise im selben Ordner wie ein Wiedergabebuch):

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

Der private Schlüssel wird jedoch weiterhin global für alle Hosts im Playbook festgelegt.

Hinweis: Sie müssen den vollständigen Pfad zur Schlüsseldatei angeben - ~ user/.ssh/some_key_rsa wird unbemerkt ignoriert.

23
tchu

Sie können einfach den Schlüssel definieren, der direkt beim Ausführen des Befehls verwendet werden soll:

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

Kopieren Einfügen:

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

Ich verwende die folgende Konfiguration:

#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

Ich hatte ein ähnliches Problem und löste es mit einem Patch für ec2.py und dem Hinzufügen einiger Konfigurationsparameter zu ec2.ini. Der Patch nimmt den Wert von ec2_key_name, stellt ihm den Wert ssh_key_path voran, fügt den Wert ssh_key_suffix am Ende hinzu und schreibt ansible_ssh_private_key_file als diesen Wert.

Die folgenden Variablen müssen zu ec2.ini in einem neuen Abschnitt 'ssh' hinzugefügt werden (dies ist optional, wenn die Standardeinstellungen Ihrer Umgebung entsprechen):

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

Hier ist der Patch für 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