Ansibleでwith_itemsループを並行して実行する方法はありますか?


12

Ansible 2.2を実行していますが、問題がなければアップグレードできます。

私はこれを見、とても興奮していましたが、このバージョン(または任意のバージョン)のAnsibleドキュメントには含まれていないようです。

私が解決しようとしている問題は、Centosボックスで管理する必要があるユーザーが1000人いることです。

このタスクを連続して実行するにはかなり時間がかかります。さらに厄介なことに、ユーザーモジュールの「expires」コマンドは常に変更されたものとしてマークを付けるため、すべてが変更されたように見えます。

これも有望に見えましたが、with_itemsループで各コマンドを実行するのに同じ時間を要し、それ以上速くなりませんでした(最後に到達するのに十分な時間待機することを気にしませんでした)。

タスクのスキップが高速になりました(Ansible 2.0の場合よりもはるかに高速です)。これを並行して実行する方法がわからない場合は、戻って無意味なタスクをスキップする方法を考えてみます。それ以外の場合は失敗します。独自のモジュールを作成します。しかし、私はこれすべてをAnsibleでもっと速くできるように思えます。


これは私が並行して実行したいもの host_authorizationsで、ユーザー名と他のデータのリストです。

  - 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

コードスニペットを入力してください。そうでなければそれは助けるのは難しいです。
030

@ 030スニペットがあります。コンテキストに少し役立つと思います。同じホストでタスクを(ループで)並列に実行する方法が本当にある場合、概念的にはもっと興味があります。私は非同期でたくさんの個々のことを行うことができますが、with_itemsではそれほどではありません。
Peter Turner

したがって、基本的には、1000人のユーザーを作成する必要がある場合は、1人のユーザーを作成するのと同じくらい速く完了する必要があります。興味深いことに、なぜLDAPのようなものを使用しないのですか?
030

1
真剣に、あなたは苦痛の道に向かっています、ユーザーの数が増えるとすぐに、誰もが集中型の会計システムに移行すると仮定しますいくつかのLDAPバックエンド(アクティブディレクトリである可能性があります)と、有効期限と公開鍵をこの中央ベースの属性として設定し、sss_ssh_authorizedkeysなどを使用して、sshサーバーがこの中央ベースから認証済みキーを取得できるようにします。
Tensibai

2
これがansibleの目的であることに同意しません(大量のユーザー作成/管理を行わないことを示唆しています)。ローカルアカウントベースでアカウントを大量に管理するべきではないという点に
同意

回答:


13

@webKnjaが述べたように、これはasyncモードで可能です。私は最近それを自分で発見し、ニーズに応じて3つの異なる方法で使用できることを学びました。

  1. 結果を実行してポーリングします。poll:5これに注意してください。これにより、結果が5秒ごとにポーリングされます。この方法で時間を節約できます。

    - 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. Fire and forget poll: 0、Ansibleはこれらのタスクを実行するだけなので、これは非常に迅速なオプションです。欠点は、タスクの結果が何であるかがわからないことchanged: True/Falseです。もちろん、フィードバックを気にすると、それはマイナス面です;)。

    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_status起動して忘れると、タスクの構文は例2と同じですが、追加のタスクが必要になりますasync_status。それは(より速く、通常のループまたは比較的速いので、これは私のお気に入りですexecute and poll)、あなたは新しいに対処する必要がありますが、フィードバックをキャプチャすることができますregisterあなたのためにasync_task

    retries: 20 -失敗するまでの試行回数。

    delay: 2 -ポーリング間で待機する秒数。

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

注意の言葉タスクヨーヨーに応じては、使用することはできませんasyncオプションを選択します。同じリソースに対する複数のリクエストを処理できないシステムとやり取りしている例がありました。async複数のホスト間で同じタスクを実行する必要がある場合は、オプションが最適に機能することがわかりました。私が最も多くの時間を「節約」できた場所です。

あなたが質問にAnsibleのドキュメントへのリンクを投稿したので、私はそれをしません。


poll例3で値を0に変更したい@chicks これは驚くべき説明です!! Thnx。
デバンジャンバス

@DebanjanBasu誰でも提案された編集を行うことができます。私はレビューキューでそれを承認する人かもしれませんが、編集自体のクレジットを取得する必要があります。
ヒヨコ

悲しいことに1文字の編集は許可されていません。:(
デバンジャンバス

2
オプション3は非常に効果的です。ただし、1つのコメント:少なくともAnsible 2.8 async_statusではjid、ではなくが必要idです。
EdwardTeach

4

あなたの質問に答えるには:いいえ、現時点では、Ansibleはループを並列で実行できません。

私が使用したいnewusers一括ユーザー作成のために作られた、代わりに。すべてのユーザーを含むファイルを作成し、ホストにコピーしてnewusers /path/to/user/listcommandタスクで実行します。


3

これを使用してasyncモードを実現することが可能です。これを行う方法については、以下の参考資料をご覧ください。

参照:

---

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

それらのリンクが壊れるようになった場合、それらのリンクが質問に答える可能性がありますが、将来の読者のためにあなたの答えに何も残っていませんが、これがあなた自身の言葉/例で問題を解決するのにどのように役立つかを示し、詳細な情報のみのリンクは残してください。
Tensibai 2018

ええ、私はA.)私がそれをテストしてB.)関連するコードがここに配置されるまで、これを回答としてマークすることはできません。しかし、私をこの方向に向けてくれてありがとう。
ピーターターナー

すみません、急いでいた:)
webKnjaZ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.