Ansible – Expect und Respones

Interaktive Skripts remote ausführen und die Eingaben vordefiniert abarbeiten lassen? Mit dem „Expect“ Modul von Ansible ist das kein Problem. Meiner Meinung nach ist diese Ansible Erweiterung einer der Mächtigsten – ohne übertreiben zu wollen ;).  Immerhin hatte dieses Modul eines meiner bisher wichtigsten Projekte in trockene Tücher gelegt. Nach ungefähr 800 Zeilen YAML Code stand ich auf einmal vor der Herausforderung, zwei interaktive Scripts auszuführen. Mir kam zuerst in den Sinn, dass auszuführende Bash Script zu analysieren und mittels YAML für Ansible zu übersetzen – der Termindruck verhinderte dies jedoch. Also begann die Suche nach einer Alternative, mit Erfolg! Ansible Expect brachte genau das, wonach ich gesucht hatte.

What we expect

“Expect the unexpected”. Nein, das Zitat ist an dieser Stelle leider falsch. Wir müssen genau wissen was uns erwartet. Bevor wir mit dem YAML Code starten, sollten wir das zu automatisierende Skript vollständig durchlaufen und uns die einzelnen Eingaben zwischenspeichern. Es ist außerdem ratsam, die Ausführungen zuerst in einer Testumgebung laufen zu lassen.

Um die ersten Schritte zu veranschaulichen, möchte ich eine pgadmin4 web Installation unter Linux vorschlagen. Für die Initialisierung des Apache Webservers muss ein Bash Skript ausgeführt werden – perfekt für Ansible Expect! Nachdem wir für unser Beispiel das setup-web.sh Skript ausgeführt und uns alle interaktiven Eingaben notiert haben, können wir mit dem YAML Code für Ansible starten.

Wir definieren das Expect Modul und geben als command den Pfad zum Bash Skript an.

- name: install pgAdmin4-web
  become: true
  expect:
    command: /usr/pgadmin4/bin/setup-web.sh

Danach geben wir unsere Responses als Dictonary an. Als Key geben wir die Abfrage im Skript in Form einer Regular Expression (RegEx) an. Unser Value ist dann die Eingabe.

- name: install pgAdmin4-web
  become: true
  expect:
    command: /usr/pgadmin4/bin/setup-web.sh
    responses:
          'Email\ address:': "me@mydomain.de"
          'Password': "mypassword"
          'Retype\ password:': "mypassword"
          'Do\ you\ wish\ to\ continue\ \(y\/n\)\?': "y"
          'The\ Apache\ web\ server\ is\ running\ and\ must\ be\ restarted\ for\ the\ pgAdmin\ 4\ installation\ to\ complete\.\ Continue\ \(y\/n\)\? ': "y"

Mehr ist tatsächlich nicht zu machen. Noch eine Empfehlung dazu: Damit das Skript nicht mit jedem Ansible Run ausgeführt wird, sollte die Ausführung des Expect Moduls innerhalb eines Blocks und einer Condition ausgeführt werden. Das könnte für pgadmin4 web beispielsweise so aussehen:

- name: check pgadmin4-web installation state
  ignore_errors: true
  shell: apt list --installed | grep pgadmin4-web
  register: pgadmin4_installation_state

- name: skip the installation if pgadmin4-web is already installed
  block:

     ### installation ###

     ### expect ###

  when: "'pgadmin4-web' not in pgadmin4_installation_state.stdout"

Sich wiederholende Abfragen

Es kann auf vorkommen, dass sich gleiche Abfragen innerhalb eines Skripts wiederholen. Zum Beispiel „Sind Sie sicher?“. Solche Abfragen können bei der Ausführung von Expect für Probleme sorgen, besonders wenn wir auf die gleiche Frage auch unterschiedliche Antworten liefern möchten. Aber auch dafür gibt es eine Lösung: Als Value eines Response kann eine Liste angegeben werden. Die Liste wird dann in der angegeben Reihenfolge abgearbeitet.

- name: run some script
  expect:
    command: /path/to/my/script
    responses:
       'Email\ address:': "me@mydomain.de"
       'Password': "mypassword"
       '(?i)Enter\ a\ number\,\ and\ hit\ ENTER\:\ '
          - "5"
          - "1"

Bei der ersten „Enter a number, and hin ENTER:“ Abfrage wird die Eingabe „5“ durchgeführt. Wenn „Enter a number, and hin ENTER:“ zum zweiten Mal abgefragt wird, gibt Ansible die „1“ an.

Beginne damit, deinen Suchbegriff oben einzugeben und drücke Enter für die Suche. Drücke ESC, um abzubrechen.

Zurück nach oben