web-dev-qa-db-fra.com

Les gestionnaires Ansible définis dans les rôles sont-ils exécutés après l'intégralité du playbook ou du rôle?

J'utilise Ansible 2.0, et je pourrais simplement l'exécuter, mais je pourrais aussi être trompé en croyant quelque chose qui n'est pas vrai par mes tests empiriques et je ne trouve aucune documentation pour me dire quand les gestionnaires sont censés être exécutés.

Si les gestionnaires ne sont pas exécutés à la fin de leurs tâches, c'est mon énigme. J'ai un livre de jeu avec 5 rôles, je veux ajouter un 6 rôle à la fin qui doit avoir terminé les gestionnaires du 4ème rôle avant qu'il puisse commencer.

Existe-t-il un moyen d'exécuter Ansible pour que le gestionnaire soit terminé (c'est-à-dire un rôle complètement terminé) avant de faire autre chose ou est-ce que j'utilise mal les gestionnaires?

13
Peter Turner

Les gestionnaires sont exécutés:

  • à la fin d'une pièce (pas de playbook)
  • lors de l'exécution du meta: flush_handlers tâche

Donc " pour ajouter un rôle 6 à la fin qui doit avoir les gestionnaires du 4ème rôle " vous avez besoin:

  • soit de diviser l'attribution de rôle en jeux séparés;
  • ou ajoutez une méta-tâche et incluez le 6ème rôle avec include_role module :

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

Pour votre cas d'utilisation, je suggère la première méthode comme include_role le module est encore très récent et il y a des bizarreries lors de son utilisation (voir cette question sur SO ).


De plus, veuillez noter que les noms des gestionnaires et les appels d'écoute sont globaux, donc deux gestionnaires dans des rôles distincts seront en conflit s'ils avaient le même nom et que les deux rôles ont été attribués en une seule fois. (réf. Gestionnaires: exécution d'opérations sur modification )

Les gestionnaires [] sont référencés par un nom globalement unique et sont notifiés par les notifiants. [] un gestionnaire, il ne s'exécutera qu'une seule fois, une fois toutes les tâches terminées dans un jeu particulier.

Les noms des gestionnaires et les sujets d'écoute en direct dans un espace de noms global.


  • Preuve empirique (exécutez ce script Shell pour confirmer que les gestionnaires sont exécutés à la fin de la pièce - il y avait des commentaires et des réponses contradictoires ici):

    #!/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
    

    Résultat:

    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"
    
  • Lecture modifiée pour contenir 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"
    

    Le résultat:

    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"
    
17
techraf

Les gestionnaires sont des listes de tâches, pas vraiment différentes des tâches normales, qui sont référencées par un nom globalement unique et qui sont notifiées par les notifiants. Si rien n'informe un gestionnaire, il ne s'exécutera pas. Quel que soit le nombre de tâches notifiées à un gestionnaire, il ne s'exécutera qu'une seule fois, une fois toutes les tâches terminées dans un jeu particulier. doc ansible

1) Les gestionnaires qui font la même chose doivent être nommés de la même manière.
restart nginx TOUJOURS redémarre nginx, pas handler1 et handler2

2) Les gestionnaires sont exécutés à la FIN de l'ensemble du "jeu", un jeu limité à vos sections.

3) J'utiliserais les fonctions register et when pour les tâches qui devraient être redémarrées, notez que cette var doit être avec vous.

Source du code

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

Beaucoup de façons de faire la même tâche. Les gestionnaires ont été conçus pour empêcher le redémarrage du même processus plusieurs fois, comme les modifications multiples d'un serveur nginx qui a des sites Web, des certificats SSL et d'autres tâches qui nécessitent des redémarrages de service.

2
Jacob Evans