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:
- Hoe kan ik
~/.ssh/SSHKEY.pem
definiëren in Ansible-bestanden in plaats van op de opdrachtregel? - Is er een parameter in playbooks (zoals
gather_facts
) om te bepalen welke privésleutels welke hosts moeten gebruiken? - 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)