ロールで定義されたAnsibleハンドラーは、プレイブック全体またはロールの後に実行されましたか?


12

私はAnsible 2.0を実行していますが、これを実行することはできますが、経験的なテストでは真実ではないことを信じるようにだまされる可能性があり、ハンドラーが実行されることになっていることを知らせるドキュメントが見つかりません

ハンドラーがタスクの最後に実行されない場合、これは私の難問です。5つのロールが含まれるプレイブックがあります。4つのロールのハンドラーを開始する前に完了する必要がある6つのロールを最後に追加します。

Ansibleを実行して、他の処理を行う前に完了したハンドラー(完全に完了したロール)に依存する方法はありますか、またはハンドラーを間違って使用していますか?

回答:


15

ハンドラーが実行されます:

  • プレイの最後(プレイブックではない)
  • 実行中のmeta: flush_handlersタスクを

したがって、「4番目のロールのハンドラーが必要な6つのロールを最後に追加するには」が必要です。

  • 役割の割り当てを別々の演劇に分割するか、
  • または、メタタスクを追加して、include_roleモジュールに 6番目のロールを含めます

    roles:
      - role4
    tasks:
      - meta: flush_handlers
      - include_role:
          name: role6
    

あなたのユースケースでinclude_roleは、モジュールがまだ非常に新鮮であり、それを使用するときに奇妙な点があるため、最初の方法をお勧めします(SOに関するこの質問を参照してください)。


さらに、ハンドラーの名前とリッスンコールはグローバルであるため、別々のロールの2つのハンドラーが同じ名前を持ち、両方のロールが1回のプレイで割り当てられた場合、競合します。(ref。ハンドラー:変更時の操作の実行

ハンドラー[]はグローバルに一意の名前で参照され、通知者によって通知されます。[]ハンドラー。特定のプレイですべてのタスクが完了した後、一度だけ実行されます。

ハンドラー名とリッスントピックは、グローバル名前空間に存在します。


  • 実証的証明(このシェルスクリプトを実行して、プレイの最後にハンドラーが実行されることを確認します-矛盾するコメントと回答がありました):

    #!/bin/bash
    
    mkdir -p ./sf831880/roles/role1
    mkdir -p ./sf831880/roles/role1/handlers
    mkdir -p ./sf831880/roles/role1/tasks
    mkdir -p ./sf831880/roles/role2
    mkdir -p ./sf831880/roles/role2/handlers
    mkdir -p ./sf831880/roles/role2/tasks
    
    cat >./sf831880/roles/role1/tasks/main.yml <<TASKS1_END
    ---
    - name: Always true in role1
      command: echo role1
      notify: handler1
    TASKS1_END
    
    cat >./sf831880/roles/role2/tasks/main.yml <<TASKS2_END
    ---
    - name: Always true in role2
      command: echo role2
      notify: handler2
    TASKS2_END
    
    cat >./sf831880/roles/role1/handlers/main.yml <<HANDLERS1_END
    ---
    - name: handler1
      debug:
        msg: "This is a handler in role1"
    HANDLERS1_END
    
    cat >./sf831880/roles/role2/handlers/main.yml <<HANDLERS2_END
    ---
    - name: handler2
      debug:
        msg: "This is a handler in role2"
    HANDLERS2_END
    
    cat >./sf831880/playbook.yml <<PLAYBOOK_END
    ---
    - hosts: localhost
      gather_facts: no
      connection: local
      roles:
        - role1
        - role2
      tasks:
        - debug:
            msg: "This is a task in a play"
    PLAYBOOK_END
    
    ansible-playbook ./sf831880/playbook.yml
    

    結果:

    PLAY [localhost] ***************************************************************
    
    TASK [role1 : Always true in role1] ********************************************
    changed: [localhost]
    
    TASK [role2 : Always true in role2] ********************************************
    changed: [localhost]
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "msg": "This is a task in a play"
    }
    
    RUNNING HANDLER [role1 : handler1] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role1"
    }
    
    RUNNING HANDLER [role2 : handler2] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role2"
    
  • 含むように修正されたプレイmeta: flush_handlers

    ---
    - hosts: localhost
      gather_facts: no
      connection: local
      roles:
        - role1
        - role2
      tasks:
        - meta: flush_handlers
        - debug:
            msg: "This is a task in a play"
    

    結果:

    PLAY [localhost] ***************************************************************
    
    TASK [role1 : Always true in role1] ********************************************
    changed: [localhost]
    
    TASK [role2 : Always true in role2] ********************************************
    changed: [localhost]
    
    RUNNING HANDLER [role1 : handler1] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role1"
    }
    
    RUNNING HANDLER [role2 : handler2] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role2"
    }
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "msg": "This is a task in a play"
    

2

ハンドラーはタスクのリストであり、実際には通常のタスクとは異なりません。グローバルに一意の名前で参照され、通知者によって通知されます。何もハンドラに通知しない場合、実行されません。ハンドラーに通知するタスクの数に関係なく、特定のプレイですべてのタスクが完了した後、ハンドラーは1回だけ実行されます。ansible doc

1)同じことを行うハンドラーには同じ名前を付ける必要があります。
restart nginx常にnginxを再起動しますhandler1しますhandler2

2)ハンドラーは、セクションにスコープされたプレイ全体の「プレイ」の終わりに実行されます。

3)再起動する必要のあるタスクにregisterwhen関数を使用します。この変数は持ち運ぶ必要があります。

コードソース

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Play 1"
}

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role2 : Run if change in task c of role 1] *******************************
changed: [localhost]

TASK [role2 : Always true in role2] ********************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "This is a task in a play"
}

RUNNING HANDLER [role1 : handler] **********************************************
ok: [localhost] => {
    "msg": "This is a handler in role1"
}

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Play 2"
}

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role2 : Run if change in task c of role 1] *******************************
changed: [localhost]

TASK [role2 : Always true in role2] ********************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "This is a task in a play"
}

RUNNING HANDLER [role1 : handler] **********************************************
ok: [localhost] => {
    "msg": "This is a handler in role1"
}

PLAY RECAP *********************************************************************
localhost                  : ok=20   changed=14   unreachable=0    failed=0

同じタスクを実行する多くの方法。ハンドラーは、Webサイト、ssl証明書、およびサービスの再起動が必要な他のタスクを持つnginxサーバーへの複数の変更など、同じプロセスを複数回再起動しないように設計されました。


特定のプレイですべてのタスクが完了した後、1回だけ実行する」と引用し、「すべての役割の最後にタスクを実行する」とまったく異なるものを要求します。あなたの主張も現実とは異なります。
テクラフ

サーバー役割から同じハンドラーをmetaから4回呼び出した場合、誤解しないでください。一度だけ実行されます
ジェイコブエヴァンス

質問は明確である:ときのハンドラが実行されていますか?実行回数ではありません。そして、彼らは役割の終わりではなく、演劇の終わりに実行されます。限目。あなたはこの主張が間違っていることを示す例で私の答えを投稿した後にあなたがそれをしたとしても、あなたはそうでないと主張する第三者です。
テクラフ

私の答えは、ロール内で再起動する必要があるアイテムのハンドラーではなく、タスクを使用することです。
ジェイコブエヴァンス

@techrafそこにいます。
ジェイコブエヴァンス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.