Wie gebe ich ein Sudo-Passwort für Ansible auf nicht interaktive Weise an?
Ich lasse Ansible Playbook so laufen:
ansible-playbook playbook.yml -i inventory.ini --user=username --ask-Sudo-pass
Aber ich möchte es so ausführen:
ansible-playbook playbook.yml -i inventory.ini --user=username
--Sudo-pass = 12345
Gibt es einen Weg? Ich möchte meine Projektbereitstellung so weit wie möglich automatisieren.
Sie können Variable in der Befehlszeile über --extra-vars "name=value"
übergeben. Sudo-Passwortvariable ist ansible_Sudo_pass
. Ihr Befehl würde also so aussehen:
ansible-playbook playbook.yml -i inventory.ini --user=username \
--extra-vars "ansible_Sudo_pass=yourPassword"
Update 2017 : Ansible 2.2.1.0 verwendet jetzt var ansible_become_pass
. Beides scheint zu funktionieren.
Die docsstark empfehlen, das Sudo-Kennwort nicht im Klartext festzulegen und stattdessen --ask-Sudo-pass
in der Befehlszeile zu verwenden, wenn ansible-playbook
ausgeführt wird.
2016 Update:
Ansible 2.0 (nicht 100%, wenn) --ask-Sudo-pass
als veraltet markiert. Die docs empfehlen jetzt die Verwendung von --ask-become-pass
, während die Verwendung von Sudo
in den gesamten Playbooks durch become
ersetzt wird.
Möglicherweise ist dies der beste Weg - vorausgesetzt, Sie können die von Scottod bereitgestellte NOPASSWD-Lösung nicht verwenden, wenn Sie die Lösung von Mircea Vutcovici in Kombination mit Ansible Vault verwenden.
Zum Beispiel könnten Sie ein Spielbuch wie das Folgende haben:
- hosts: all
vars_files:
- secret
tasks:
- name: Do something as Sudo
service: name=nginx state=restarted
Sudo: yes
Hier ist eine Datei namens secret
enthalten, die unser Sudo-Passwort enthält.
Wir werden ansible-vault verwenden, um eine verschlüsselte Version dieser Datei zu erstellen:
ansible-vault create secret
Daraufhin werden Sie nach einem Kennwort gefragt. Öffnen Sie dann Ihren Standardeditor, um die Datei zu bearbeiten. Sie können hier Ihren ansible_Sudo_pass
eingeben.
beispiel: secret
:
ansible_Sudo_pass: mysudopassword
Speichern und beenden Sie, jetzt haben Sie eine verschlüsselte secret
-Datei, die Ansible entschlüsseln kann, wenn Sie Ihr Playbook ausführen. Hinweis: Sie können die Datei mit ansible-vault edit secret
bearbeiten (und das Kennwort eingeben, das Sie beim Erstellen der Datei verwendet haben).
Das letzte Puzzleteil besteht darin, Ansible mit einem --vault-password-file
zu versehen, mit dem Ihre secret
-Datei entschlüsselt wird.
Erstellen Sie eine Datei mit dem Namen vault.txt
und geben Sie das Kennwort ein, das Sie beim Erstellen Ihrer secret
-Datei verwendet haben. Das Passwort sollte eine Zeichenfolge sein, die als einzelne Zeile in der Datei gespeichert ist.
Aus den Ansible-Dokumenten:
Stellen Sie sicher, dass die Berechtigungen für die Datei so sind, dass niemand anderes auf Ihren Schlüssel zugreifen kann und Ihren Schlüssel nicht zur Quellcodeverwaltung hinzufügen kann
Endlich: Sie können jetzt Ihr Spielbuch mit so etwas laufen lassen
ansible-playbook playbook.yml -u someuser -i hosts --Sudo --vault-password-file=vault.txt
Das Obige setzt das folgende Verzeichnislayout voraus:
.
|_ playbook.yml
|_ secret
|_ hosts
|_ vault.txt
Weitere Informationen zu Ansible Vault finden Sie hier: https://docs.ansible.com/playbooks_vault.html
Wenn Sie sich den Code ( runner/__init__.py
) anschauen, können Sie ihn wahrscheinlich in Ihrer Inventardatei festlegen:
[whatever]
some-Host ansible_Sudo_pass='foobar'
Es scheint auch etwas in ansible.cfg
config zu geben, das aber momentan noch nicht implementiert ist ( constants.py
).
Ich glaube nicht, dass Ansible es Ihnen erlaubt, ein Kennwort in den Flags anzugeben, wie Sie möchten. Es kann irgendwo in den Konfigurationen gesetzt werden, aber dies würde die Verwendung von Ansible insgesamt weniger sicher machen und würde nicht empfohlen werden.
Sie können zum Beispiel einen Benutzer auf dem Zielcomputer erstellen und ihm kennwortlose Sudo-Berechtigungen für alle Befehle oder eine eingeschränkte Befehlsliste erteilen.
Wenn Sie Sudo visudo
ausführen und eine Zeile wie die unten stehende eingeben, muss der Benutzer 'privilegedUser' kein Kennwort eingeben, wenn er etwas wie Sudo service xxxx start
ausführt:
%privilegedUser ALL= NOPASSWD: /usr/bin/service
Das Sudo-Passwort wird als Variable mit dem Namen ansible_Sudo_pass
gespeichert. Sie können diese Variable auf verschiedene Arten einstellen:
Pro Host in Ihrer Inventar-Hostdatei (inventory/<inventoryname>/hosts
)
[server]
10.0.0.0 ansible_Sudo_pass=foobar
Pro Gruppe in Ihrer Bestandsgruppendatei (inventory/<inventoryname>/groups
)
[server:vars]
ansible_Sudo_pass=foobar
Pro Gruppe, in Gruppenvariablen (group_vars/<groupname>/ansible.yml
)
ansible_Sudo_pass: "foobar"
Pro Gruppe, verschlüsselt (ansible-vault create group_vars/<groupname>/ansible.yml
)
ansible_Sudo_pass: "foobar"
Sie können das Kennwort für eine Gruppe oder für alle Server gleichzeitig festlegen:
[all:vars]
ansible_Sudo_pass=default_Sudo_password_for_all_hosts
[group1:vars]
ansible_Sudo_pass=default_Sudo_password_for_group1
Ich riss mir die Haare aus, jetzt habe ich eine Lösung gefunden, die macht, was ich will:
1 verschlüsselte Datei pro Host mit dem Sudo-Passwort
/ etc/ansible/hosts:
[all:vars]
ansible_ssh_connection=ssh ansible_ssh_user=myuser ansible_ssh_private_key_file=~/.ssh/id_rsa
[some_service_group]
node-0
node-1
dann erstellen Sie für jeden Host eine verschlüsselte var-Datei wie folgt:
ansible-vault create /etc/ansible/Host_vars/node-0
mit inhalt
ansible_Sudo_pass: "my_Sudo_pass_for_Host_node-0"
wie Sie das Tresorpasswort einrichten (über --ask-vault-pass eingeben) oder per cfg entscheiden, liegt bei Ihnen
ich vermute, Sie können die gesamte Hosts-Datei einfach verschlüsseln ...
Ein geschickter Weg, dies zu tun, besteht darin, Ihr Sudo
-Passwort in einem sicheren Tresor wie LastPass oder KeePass zu speichern und es dann mit ansible-playbook
an [email protected]
zu übergeben, aber den Inhalt in einer tatsächlichen Datei nicht fest zu codieren Sie können das Konstrukt [email protected]<(...)
verwenden, um einen Befehl in einer Sub-Shell auszuführen und seine Ausgabe (STDOUT) an einen anonymen Dateideskriptor umzuleiten, wodurch das Kennwort effektiv an [email protected]<(..)
übergeben wird.
$ ansible-playbook -i /tmp/hosts pb.yml \
[email protected]<(echo "ansible_Sudo_pass: $(lpass show folder1/item1 --password)")
Das oben Genannte tut mehrere Dinge, lasst es uns brechen.
ansible-playbook -i /tmp/hosts pb.yml
- Natürlich wird ein Playbook über ein Ansible-Playbook ausgeführt$(lpass show folder1/item1 --password)"
- führt die LastPass-CLI lpass
aus und ruft das zu verwendende Kennwort abecho "ansible_Sudo_pass: ...password..."
- nimmt die Zeichenfolge 'ansible_Sudo_pass:' und kombiniert sie mit dem von lpass
angegebenen Kennwort.[email protected]<(..)
- fügt das Obige zusammen und verbindet die Subshell von <(...)
als Dateideskriptor, damit ansible-playbook
verbraucht werden kann.Wenn Sie das nicht jedes Mal eingeben möchten, können Sie die Dinge einfach so machen. Erstellen Sie zunächst einen Alias in Ihrem .bashrc
wie folgt:
$ cat ~/.bashrc
alias asp='echo "ansible_Sudo_pass: $(lpass show folder1/item1 --password)"'
Jetzt kannst du dein Playbook so ausführen:
$ ansible-playbook -i /tmp/hosts pb.yml [email protected]<(asp)
Wenn Sie mit dem Speichern von Kennwörtern in Klartextdateien vertraut sind, können Sie als Option eine JSON-Datei mit dem Parameter --extra-vars verwenden.
ansible-playbook --extra-vars "@private_vars.json" playbook.yml
Ansible vault wurde hier schon ein paar Mal vorgeschlagen, aber ich bevorzuge git-crypt zum Verschlüsseln vertraulicher Dateien in meinen Spielbüchern. Wenn Sie git verwenden, um Ihre Spielbücher aufzubewahren, ist das ein Kinderspiel. Das Problem, das ich mit Ansible Vault gefunden habe, ist, dass ich unvermeidlich auf verschlüsselte Kopien der Datei stoße, mit der ich arbeiten möchte, und diese entschlüsseln muss, bevor ich arbeiten kann. git-crypt
bietet einen schöneren Workflow-IMO.
Auf diese Weise können Sie Ihre Passwörter in einem var in Ihr Playbook einfügen und Ihr Playbook als verschlüsselte Datei in .gitattributes
wie folgt markieren:
my_playbook.yml filter=git-crypt diff=git-crypt
Ihr Spielbuch wird auf Github transparent verschlüsselt. Dann müssen Sie entweder den Verschlüsselungsschlüssel auf dem Host installieren, den Sie zum Ausführen von ansible verwenden, oder den Anweisungen in der Dokumentation folgen, um ihn mit gpg
einzurichten.
Es gibt gute Fragen und Antworten zum Weiterleiten von gpg
-Schlüsseln wie Ihrem ssh-agent
, um SSH-Schlüssel hier weiterzuleiten: https://superuser.com/questions/161973/how-can-i-forward-a-gpg-key-via-ssh-agent .
sie können das Sudo-Passwort für Ihr Spielbuch in der Hosts-Datei wie folgt schreiben:
[Host-group-name]
Host-name:port ansible_Sudo_pass='*your-Sudo-password*'
Sie können verwenden ansible Gewölbe Dadurch wird Ihr Passwort in einem verschlüsselten Tresor verschlüsselt. Danach können Sie Variable aus Tresor in Playbooks verwenden.
Einige Dokumentationen zu ansible vault:
http://docs.ansible.com/playbooks_vault.html
Wir verwenden es als Tresor pro Umgebung. Zum Bearbeiten des Tresors haben wir den Befehl:ansible-vault edit inventories/production/group_vars/all/vault
Wenn Sie eine Tresorvariable aufrufen möchten, müssen Sie ansible-playbook mit folgenden Parametern verwenden:ansible-playbook -s --vault-password-file=~/.ansible_vault.password
Ja, wir speichern das Tresorkennwort im lokalen Verzeichnis im Klartext, aber es ist nicht gefährlicher als das Speichern des Root-Kennworts für jedes System. Das Root-Passwort befindet sich in der Tresordatei oder Sie können es wie eine Sudoers-Datei für Ihren Benutzer/Ihre Gruppe haben.
Ich empfehle die Verwendung der sudoers-Datei auf dem Server. Hier ist ein Beispiel für den Gruppenadministrator:%admin ALL=(ALL) NOPASSWD:ALL
Sie können das Dienstprogramm sshpass
wie folgt verwenden:
$ sshpass -p "your pass" ansible pattern -m module -a args \
-i inventory --ask-Sudo-pass
Rufen Sie einfach Ihr Playbook mit --extra-vars "become_pass=Password"
an.
become_pass = ('ansible_become_password', 'ansible_become_pass')
Die Verwendung von ansible 2.4.1.0 und Folgendes muss funktionieren:
[all]
17.26.131.10
17.26.131.11
17.26.131.12
17.26.131.13
17.26.131.14
[all:vars]
ansible_connection=ssh
ansible_user=per
ansible_ssh_pass=per
ansible_Sudo_pass=per
Führen Sie einfach das playbook mit diesem Inventar aus als:
ansible-playbook -i inventory copyTest.yml
Mein Hack, um dies zu automatisieren, war es, eine Umgebungsvariable zu verwenden und über --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"
darauf zuzugreifen.
Exportieren Sie eine Umgebungsvariable, aber vermeiden Sie den Bash-/Shell-Verlauf (voranstellen eines Leerzeichens oder anderer Methoden). Z.B.:
export ANSIBLE_BECOME_PASS='<your password>'
Suchen Sie die Umgebungsvariable, während Sie die zusätzliche Variable ansible_become_pass
an ansible-playbook
übergeben, z.
ansible-playbook playbook.yml -i inventories/dev/hosts.yml -u user --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"
Gute alternative Antworten:
ansible_become_pass
. Das ist anständig. Für die paranoiden Teams, die ansteckende Tresorkennwörter teilen und ansteckende Spiele mit einzelnen Konten ausführen müssen, müssen sie das ansteckende Tresorkennwort verwenden, um das Betriebssystemkennwort (Identitätsdiebstahl) der jeweils anderen Benutzer umzukehren. Sie müssen Ihrem eigenen Team vertrauen?@
verwendet, um die ansible-Variable aus dem Dateideskriptor zu lesen . Vermeidet zumindest die Bash-Geschichte. Nicht sicher, aber hoffentlich wird das Subshell-Echo in der Überwachungsprotokollierung (z. B. auditd) nicht abgefangen und angezeigt.Nur ein Nachtrag, also macht niemand anderes den Ärger durch, den ich kürzlich gemacht habe:
AFAIK, die beste Lösung ist die allgemeine von toast38coza. Wenn es sinnvoll ist, Ihre Kennwortdateien und Ihr Spielbuch statisch miteinander zu verknüpfen, folgen Sie seiner Vorlage mit vars_files
(oder include_vars
). Wenn Sie sie getrennt halten möchten, können Sie den Inhalt des Tresors in der Befehlszeile wie folgt angeben:
ansible-playbook --ask-vault-pass [email protected]<PATH_TO_VAULT_FILE> <PLAYBOOK_FILE>
Das ist im Nachhinein offensichtlich, aber hier sind die Sprüche:
Dieses blutige @ Zeichen. Wenn Sie es weglassen, wird das Analysieren im Hintergrund fehlschlagen, und Ansible-Playbook wird so fortgesetzt, als hätten Sie die Datei nie an erster Stelle angegeben.
Sie müssen den Inhalt des Tresors explizit importieren, entweder über die Befehlszeile --extra-vars/-e oder innerhalb Ihres YAML-Codes. Das --ask-vault-pass
-Flag führt an sich nichts aus (abgesehen von der Eingabeaufforderung für einen Wert, der später verwendet werden kann oder nicht).
Vielleicht fügen Sie Ihr "@" ein und sparen eine Stunde.
wir können auch EXPECT BLOCK in Ansible verwenden, um Bash zu erzeugen und es an Ihre Bedürfnisse anzupassen
- name: Run expect to INSTALL TA
Shell: |
set timeout 100
spawn /bin/sh -i
expect -re "$ "
send "Sudo yum remove -y xyz\n"
expect "$ "
send "Sudo yum localinstall -y {{ rpm_remotehost_path_for_xyz }}\n"
expect "~]$ "
send "\n"
exit 0
args:
executable: /usr/bin/expect
Die obige Lösung von @ toast38coza hat bei mir funktioniert. nur das Sudo: yes ist jetzt in Ansible veraltet. Verwenden Sie stattdessen werden und werden_Benutzer .
tasks:
- name: Restart Apache service
service: name=Apache2 state=restarted
become: yes
become_user: root
Sehr einfach und nur in der Variablendatei einfügen
Beispiel:
$ vim group_vars/all
Und fügen Sie diese hinzu:
Ansible_connection: ssh
Ansible_ssh_user: rafael
Ansible_ssh_pass: password123
Ansible_become_pass: password123
Nach fünf Jahren sehe ich, dass dies immer noch ein sehr relevantes Thema ist. Ein wenig die Antwort von Leucos widerspiegelnd, die ich in meinem Fall am besten finde, wenn ich nur ansible Tools verwende (ohne zentrale Authentifizierung, Token oder was auch immer). Dies setzt voraus, dass Sie auf allen Servern denselben Benutzernamen und denselben öffentlichen Schlüssel haben. Andernfalls müssten Sie natürlich genauer vorgehen und die entsprechenden Variablen neben den Hosts hinzufügen:
[all:vars]
ansible_ssh_user=ansible
ansible_ssh_private_key_file=home/user/.ssh/mykey
[group]
192.168.0.50 ansible_Sudo_pass='{{ myserver_Sudo }}'
ansible-vault create mypasswd.yml
ansible-vault edit mypasswd.yml
Hinzufügen:
myserver_Sudo: mysecretpassword
Dann:
ansible-playbook -i inv.ini my_role.yml --ask-vault --extra-vars '@passwd.yml'
Zumindest müssen Sie auf diese Weise nicht mehr die Variablen schreiben, die auf die Passwörter verweisen.