Gibt es eine Möglichkeit, with_items-Schleifen in Ansible parallel auszuführen?


12

Ich verwende Ansible 2.2, kann aber ein Upgrade durchführen, wenn es hilft.

Ich habe das gesehen und war ziemlich aufgeregt, aber es scheint nicht in dieser (oder einer anderen) Version der Ansible-Dokumentation zu sein.

Das Problem, das ich zu lösen versuche, ist, dass ich 1000 Benutzer habe, die ich auf einer Centos-Box verwalten muss.

Es dauert eine Weile, diese Aufgabe seriell auszuführen. Und noch ärgerlicher ist, dass alles als geändert angezeigt wird, da der Befehl "expires" auf dem Benutzermodul das Objekt immer als geändert markiert.

Dies sah ebenfalls vielversprechend aus, aber es dauerte genauso lange, bis jeder Befehl in der with_items-Schleife ausgeführt wurde, und ging nicht schneller (ich habe nie lange genug gewartet, um bis zum Ende zu kommen).

Das Überspringen von Aufgaben ist jetzt schnell (viel schneller als in Ansible 2.0). Wenn ich nicht herausfinden kann, wie dies parallel funktioniert, werde ich zurückgehen und herausfinden, wie sinnlose Aufgaben übersprungen werden können, und wenn überhaupt sonst schlägt fehl, ich schreibe mein eigenes Modul. Aber es scheint, als sollte ich das alles in Ansible schneller machen können.


Dies ist, was ich parallel ausführen möchte, host_authorizationsist eine Liste von Benutzernamen und anderen Daten.

  - name: Create/modify OS user accounts
    user: name={{ item.username }} group=sshusers shell=/bin/bash home="/home/selinux-modules/{{ item.username }}" state=present expires={{item.expiredate|default(omit)}}
    with_items: "{{ host_authorizations }}"
    tags: full_maintenance

Bitte geben Sie einen Code-Ausschnitt an. Ansonsten ist es schwer zu helfen.
030

@ 030 gibt es ein Snippet, ich denke, es hilft ein bisschen für den Kontext. Ich bin konzeptionell mehr daran interessiert, ob es wirklich eine Möglichkeit gibt, Aufgaben (in einer Schleife) parallel auf demselben Host auszuführen. Ich weiß, dass ich mit async eine Menge einzelner Dinge tun kann, aber nicht so sehr mit with_items.
Peter Turner

Wenn also 1000 Benutzer erstellt werden müssen, sollte dies genauso schnell abgeschlossen sein wie das Erstellen nur eines Benutzers. Interessant, warum nicht so etwas wie LDAP verwenden?
030

1
Im Ernst, Sie befinden sich auf einem schmerzhaften Weg. Ich glaube, niemand verwaltet mehr als ein Dutzend Konten mit lokaler Kontobasis. Sobald die Anzahl der Benutzer steigt, gehe ich davon aus, dass alle normalerweise auf ein zentrales Buchhaltungssystem umsteigen Einige LDAP-Backends (könnten Active Directory sein) und legen dann die Ablaufzeit und den öffentlichen Schlüssel als Attribute dieser zentralen Basis fest. Verwenden Sie dann Dinge wie sss_ssh_authorizedkeys, damit der SSH-Server die autorisierten Schlüssel von dieser zentralen Basis erhält.
Tensibai

2
Ich bin nicht der Meinung, dass dies das ist, wofür ansible ist (Hinweis darauf, dass es keine Massenbenutzererstellung / -verwaltung durchführt). Ich stehe zu dem Punkt, dass Konten nicht auf lokaler
Kontobasis

Antworten:


13

Wie @webKnja erwähnt hat, ist dies im asyncModus möglich . Ich habe es kürzlich selbst entdeckt und gelernt, dass Sie es je nach Ihren Anforderungen auf drei verschiedene Arten verwenden können.

  1. Führen Sie die Ergebnisse aus und fragen Sie sie ab. Beachten Sie Folgendespoll:5 : Dadurch werden die Ergebnisse alle 5 Sekunden abgefragt. Mit dieser Methode können Sie Zeit sparen.

    - name: My long runing task
      some_module_name:
        ip: "{{item.fabric}}"
        username: "{{user}}"
        password: "{{password}}"
        secret: "{{secret}}"
      loop: "{{zoning_list}}"
      register: _alias_vc_0
      async: 60
      poll: 5
    
  2. Feuer und vergessen poll: 0 , Dies ist eine sehr schnelle Option, da Ansible nur diese Aufgaben erledigt. Der Nachteil ist, dass wir nicht wissen, was das Ergebnis der Aufgabe war, dh changed: True/False. Natürlich ist es ein Nachteil, wenn Sie sich für das Feedback interessieren;).

    name: My long runing task
    some_module_name:
      ip: "{{item.fabric}}"
      username: "{{user}}"
      password: "{{password}}"
      secret: "{{secret}}"
    loop: "{{zoning_list}}"
    register: _alias_vc_0
    async: 60
    poll: 0
    
  3. async_statusFeuern und vergessen mit , die Syntax für die Aufgabe ist dieselbe wie in Beispiel 2, unabhängig davon, ob eine zusätzliche Aufgabe erforderlich ist async_status. Das ist mein Favorit , da es relativ schnell ist (schneller als normal Looping oder die execute and poll) und ermöglicht es Ihnen , das Feedback zu erfassen , obwohl muß mit neuen beschäftigen registerfür Ihre async_task.

    retries: 20 - wie viele Versuche vor dem Scheitern.

    delay: 2 - Wie viele Sekunden müssen zwischen den Umfragen gewartet werden?

    - name: My long runing task
      some_module_name:
        ip: "{{item.fabric}}"
        username: "{{user}}"
        password: "{{password}}"
        secret: "{{secret}}"
      loop: "{{zoning_list}}"
      register: _alias_vc_0
      async: 60
      poll: 0
    
    
    - name: Wait for My long running task to finish
      async_status:
        id: "{{ item.ansible_job_id }}"
      register: _jobs_alias_vc_0
      retries: 20
      delay: 2
      until: _jobs_alias_vc_0.finished
      loop: "{{_alias_vc_0.results}}"
    

Ein Wort der Vorsicht , abhängig von der Aufgabe, die Sie möglicherweise nicht verwenden können async. Ich hatte Beispiele, in denen ich mit einem System interagierte, das nicht mehrere Anforderungen für dieselbe Ressource verarbeiten konnte. Ich fand die asyncOption am besten, wenn ich dieselbe Aufgabe auf mehreren Hosts ausführen muss. Dort konnte ich die meiste Zeit "sparen".

Da Sie den Link zur Ansible-Dokumentation in der Frage gepostet haben, werde ich das nicht tun.


@chicks Vielleicht möchten Sie den pollWert in Beispiel 3 auf 0 ändern . Dies ist eine erstaunliche Erklärung !! Danke.
Debanjan Basu

@DebanjanBasu Jeder kann Änderungsvorschläge machen. Ich bin möglicherweise derjenige, der es in den Überprüfungswarteschlangen genehmigt, aber Sie sollten die Bearbeitung selbst gutschreiben.
Küken

Änderungen an einem Charakter sind leider nicht erlaubt! :(
Debanjan Basu

2
Option 3 funktioniert super, danke! Ein Kommentar aber: wie von mindestens ansible 2,8, async_statuserfordert jid, nicht id.
EdwardTeach

4

Um Ihre Frage zu beantworten: Nein, Ansible kann derzeit keine Schleifen parallel ausführen.

Ich würde newusersstattdessen verwenden, was für die Erstellung von Massenbenutzern gemacht ist. Erstellen Sie eine Datei mit allen Benutzern, kopieren Sie sie auf den Host und führen Sie sie newusers /path/to/user/listin einer commandAufgabe aus.


3

Dies kann im asyncModus erreicht werden. Nachfolgend finden Sie einige Referenzen dazu.

Refs:

---

- name: Run tasks in parallel
  hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: Pretend to create instances
      command: "sleep {{ item }}"  # Instead of calling a long running operation at a cloud provider, we just sleep.
      with_items:
        - 6
        - 8
        - 7
      register: _create_instances
      async: 600  # Maximum runtime in seconds. Adjust as needed.
      poll: 0  # Fire and continue (never poll)

    - name: Wait for creation to finish
      async_status:
        jid: "{{ item.ansible_job_id }}"
      register: _jobs
      until: _jobs.finished
      delay: 5  # Check every 5 seconds. Adjust as you like.
      retries: 10  # Retry up to 10 times. Adjust as needed.
      with_items: "{{ _create_instances.results }}"

Während diese Links möglicherweise die Frage beantworten, wenn sie kaputt gehen, ist in Ihrer Antwort für zukünftige Leser nichts mehr übrig. Versuchen Sie jedoch zu zeigen, wie dies zur Lösung des Problems mit Ihren eigenen Worten / Beispielen beitragen kann, und lassen Sie die Links nur für detailliertere Informationen.
Tensibai

Ja, ich kann dies nicht als Antwort markieren, bis A.) ich es teste und B.) hier relevanter Code eingefügt ist. Aber danke, dass Sie mich trotzdem in diese Richtung weisen.
Peter Turner

Entschuldigung, ich hatte es eilig :)
webKnjaZ
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.