Privé SSH-sleutels definiëren voor servers in dynamische inventarissen

Ik kwam een ​​configuratieprobleem tegen bij het coderen van een Ansible-playbook voor SSH-privésleutelbestanden. In statische Ansible-inventarissen kan ik combinaties van hostservers, IP-adressen en gerelateerde SSH-privésleutels definiëren, maar ik heb geen idee hoe ik die met dynamische inventarissen moet definiëren.

Bijvoorbeeld:

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

Ik gebruik het onderstaande commando om dat playbook op te roepen:

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

Mijn vragen zijn:

  1. Hoe kan ik ~/.ssh/SSHKEY.pemdefiniëren in Ansible-bestanden in plaats van op de opdrachtregel?
  2. Is er een parameter in playbooks (zoals gather_facts) om te bepalen welke privésleutels welke hosts moeten gebruiken?
  3. Als er geen manier is om privésleutels in bestanden te definiëren, wat moet er dan op de opdrachtregel worden aangeroepen als verschillende sleutels worden gebruikt voor verschillende hosts in dezelfde inventaris?

Antwoord 1, autoriteit 100%

TL;DR: Specificeer sleutelbestand in groepsvariabelenbestand, aangezien ‘tag_Name_server1’ een groep is.


Opmerking: ik neem aan dat je het EC2 extern inventarisatiescript. Als u een andere dynamische voorraadbenadering gebruikt, moet u deze oplossing mogelijk aanpassen.

Dit is een probleem waar ik al maanden mee worstel, en ik heb eindelijk een oplossing gevonden, dankzij de suggestie van Brian Coca hier. De truc is om Ansible’s groepsvariabele mechanismen te gebruiken om automatisch het juiste SSH-sleutelbestand door te geven voor de machine waarmee je werkt.

Het EC2-inventarisscript stelt automatisch verschillende groepen in die u kunt gebruiken om naar hosts te verwijzen. Je gebruikt dit in je playbook: in het eerste spel vertel je Ansible om ‘role1’ toe te passen op de hele ‘tag_Name_server1’-groep. We willen Ansible opdracht geven om een ​​specifieke SSH-sleutel te gebruiken voor elke host in de ‘tag_Name_server1’-groep, waar groepsvariabele bestanden binnenkomen.

Ervan uitgaande dat uw playbook zich in de directory ‘my-playbooks’ bevindt, maakt u bestanden voor elke groep in de directory ‘group_vars’:

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

Telkens wanneer u naar deze groepen in een playbook verwijst, controleert Ansible de juiste bestanden en laadt alle variabelen die u daar hebt gedefinieerd.

Binnen elk groeps-var-bestand kunnen we het sleutelbestand specificeren dat moet worden gebruikt om verbinding te maken met hosts in de groep:

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

Als je nu je playbook uitvoert, zou het automatisch de juiste toetsen moeten oppikken!


Omgevings-vars gebruiken voor draagbaarheid

Ik draai vaak playbooks op veel verschillende servers (lokaal, remote build-server, enz.), dus ik vind het leuk om dingen te parametriseren. In plaats van een vast pad te gebruiken, heb ik een omgevingsvariabele genaamd SSH_KEYDIR die verwijst naar de map waar de SSH-sleutels zijn opgeslagen.

In dit geval zien de vars-bestanden van mijn groep er in plaats daarvan als volgt uit:

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

Verdere verbeteringen

Er zijn waarschijnlijk een aantal handige manieren waarop dit kan worden verbeterd. Om te beginnen moet u nog steeds handmatig specificeren welke sleutel voor elke groep moet worden gebruikt. Aangezien het EC2-inventarisatiescript details bevat over het sleutelpaar dat voor elke server wordt gebruikt, is er waarschijnlijk een manier om de sleutelnaam rechtstreeks uit het script zelf te halen. In dat geval kunt u de directory opgeven waarin de sleutels zich bevinden (zoals hierboven) en deze de juiste sleutels laten kiezen op basis van de inventarisgegevens.


Antwoord 2, autoriteit 49%

De beste oplossing die ik voor dit probleem kon vinden, is om een ​​privésleutelbestand op te geven in ansible.cfg (ik bewaar het meestal in dezelfde map als een playbook):

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

Hoewel het nog steeds de privésleutel globaal instelt voor alle hosts in Playbook.

Opmerking: je moet het volledige pad naar het sleutelbestand specificeren – ~user/.ssh/some_key_rsa wordt stil genegeerd.


Antwoord 3, autoriteit 26%

U kunt eenvoudig de sleutel definiëren om direct te gebruiken bij het uitvoeren van de opdracht:

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

Kopiëren/plakken:

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

Antwoord 4, autoriteit 14%

Ik gebruik de volgende configuratie:

#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"

Antwoord 5, autoriteit 9%

Ik had een soortgelijk probleem en loste het op met een patch voor ec2.py en het toevoegen van enkele configuratieparameters aan ec2.ini. De patch neemt de waarde van ec2_key_name, laat het voorafgaan met het ssh_key_path, en voegt het ssh_key_suffix toe aan het einde, en schrijft ansible_ssh_private_key_file als deze waarde.

De volgende variabelen moeten worden toegevoegd aan ec2.ini in een nieuwe ‘ssh’-sectie (dit is optioneel als de standaardinstellingen overeenkomen met uw omgeving):

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

Hier is de patch voor 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)

Other episodes