Comment attendre le redémarrage du serveur avec Ansible?

j'essaie de redémarrer le serveur et puis d'attendre, en utilisant ceci:

- name: Restart server
  shell: reboot

- name: Wait for server to restart
  wait_for:
    port=22
    delay=1
    timeout=300

Mais j'obtiens cette erreur:

TASK: [iptables | Wait for server to restart] ********************************* 
fatal: [example.com] => failed to transfer file to /root/.ansible/tmp/ansible-tmp-1401138291.69-222045017562709/wait_for:
sftp> put /tmp/tmpApPR8k /root/.ansible/tmp/ansible-tmp-1401138291.69-222045017562709/wait_for

Connected to example.com.
Connection closed
40
demandé sur Greg Dubicki 2014-05-27 01:11:17

9 réponses

Vous devriez changer la tâche wait_for pour exécuter local_action, et spécifiez l'hôte que vous attendez. Par exemple:

- name: Wait for server to restart
  local_action:
    module: wait_for
      host=192.168.50.4
      port=22
      delay=1
      timeout=300
30
répondu Shahar 2014-05-27 11:35:28

(Code mis à jour pour Ansible 2.4.2.0)

Redémarrer une tâche

- name: restart server
  shell: 'sleep 1 && shutdown -r now "Reboot triggered by Ansible" && sleep 1'
  async: 1
  poll: 0
  become: true

Cela exécute la commande shell comme un tâche asynchrone, donc Ansible n'attendra pas la fin de la commande. Habituellement async param donne le temps maximum pour la tâche mais comme poll est mis à 0, Ansible ne Pollera jamais si la commande est terminée - il fera de cette commande un "feu et oubli". Dort avant et après shutdown doivent empêcher de briser la connexion SSH pendant redémarrez alors que L'option Ansible est toujours connectée à votre hôte distant.

Attendre qu'une tâche

Vous pouvez simplement utiliser:

- name: Wait for server to restart
  local_action:
    module: wait_for
      host={{ inventory_hostname }}
      port=22
      delay=10
    become: false

..mais vous pouvez préférer utiliser {{ ansible_ssh_host }} variable comme nom d'hôte et / ou {{ ansible_ssh_port }} comme hôte et port SSH si vous utilisez des entrées comme:

hostname         ansible_ssh_host=some.other.name.com ansible_ssh_port=2222 

..dans votre inventaire (Ansible hosts fichier).

exécuter wait_for tâche sur la machine qui exécute Ansible. Cette tâche va attendre que le port 22 s'ouvre sur votre hôte distant, à partir de 10 secondes de retard.

Redémarrer et attendre que les gestionnaires d'

mais je suggère d'utiliser ces deux - là comme manipulateurs, pas comme tâches.

Il y a 2 principales raisons de le faire:

  • code reuse - vous pouvez utiliser un handler pour de nombreuses tâches. Exemple: déclencher un redémarrage du serveur après avoir changé le fuseau horaire et après la modification de la noyau,

  • trigger only once-si vous utilisez un handler pour quelques tâches, et que plus d'une d'entre elles va faire un changement => trigger le handler, alors la chose que le handler fait n'arrivera qu'une seule fois. Exemple: si vous avez un gestionnaire de redémarrage httpd attaché à la modification de configuration de httpd et à la mise à jour du certificat SSL, alors dans le cas où la configuration et le certificat SSL changent, httpd ne sera redémarré qu'une seule fois.

en savoir plus sur les gestionnaires d' ici.

redémarrage et attente du redémarrage en tant que gestionnaires:

  handlers:

    - name: Restart server
      command: 'sleep 1 && shutdown -r now "Reboot triggered by Ansible" && sleep 1'
      async: 1
      poll: 0
      ignore_errors: true
      become: true

    - name: Wait for server to restart
      local_action:
        module: wait_for
          host={{ inventory_hostname }}
          port=22
          delay=10
        become: false

..et à utiliser dans votre tâche dans une séquence, comme ceci, ici couplé avec le redémarrage du serveur gestionnaire de:

  tasks:
    - name: Set hostname
        hostname: name=somename
        notify:
          - Restart server
          - Wait for server to restart

Notez que les manipulateurs sont exécutés dans l'ordre où ils sont définis, et non dans l'ordre où ils sont listés notify!

45
répondu Greg Dubicki 2018-03-12 21:44:49

le Plus fiable que j'ai avec 1.9.4 obtenu est (c'est à jour, la version originale est en bas):

- name: Example ansible play that requires reboot
  sudo: yes
  gather_facts: no
  hosts:
    - myhosts
  tasks:
    - name: example task that requires reboot
      yum: name=* state=latest
      notify: reboot sequence
  handlers:
    - name: reboot sequence
      changed_when: "true"
      debug: msg='trigger machine reboot sequence'
      notify:
        - get current time
        - reboot system
        - waiting for server to come back
        - verify a reboot was actually initiated
    - name: get current time
      command: /bin/date +%s
      register: before_reboot
      sudo: false
    - name: reboot system
      shell: sleep 2 && shutdown -r now "Ansible package updates triggered"
      async: 1
      poll: 0
      ignore_errors: true
    - name: waiting for server to come back
      local_action: wait_for host={{ inventory_hostname }} state=started delay=30 timeout=220
      sudo: false
    - name: verify a reboot was actually initiated
      # machine should have started after it has been rebooted
      shell: (( `date +%s` - `awk -F . '{print }' /proc/uptime` > {{ before_reboot.stdout }} ))
      sudo: false

Notez le async option. 1.8 et 2.0 peuvent vivre avec 0 mais de 1,9 veut 1. Ce qui précède vérifie également si la machine a effectivement été redémarrée. C'est bien parce qu'une fois j'ai eu une erreur typographique qui a échoué au redémarrage et aucune indication de l'échec.

le gros problème est d'attendre que la machine soit en place. Cette version reste là pendant 330 secondes et n'essaie jamais de l'accès de l'hôte plus tôt. D'autres réponses suggèrent d'utiliser le port 22. C'est bien si ces deux sont remplies:

  • vous avez un accès direct aux machines
  • votre machine est accessible immédiatement après l'ouverture du port 22

ce n'est pas toujours vrai donc j'ai décidé de gaspiller 5 minutes de temps de calcul.. J'espère pouvoir étendre le module wait_for pour vérifier l'état de l'hôte afin d'éviter de perdre du temps.

btw la réponse suggérant d'utiliser les gestionnaires est de nice. +1 pour les handlers de ma part (et j'ai mis à jour la réponse pour utiliser handlers).

Voici la version originale, mais il n'est pas si bon et pas si fiable:

- name: Reboot
  sudo: yes
  gather_facts: no
  hosts:
    - OSEv3:children
  tasks:
    - name: get current uptime
      shell: cat /proc/uptime | awk -F . '{print }'
      register: uptime
      sudo: false
    - name: reboot system
      shell: sleep 2 && shutdown -r now "Ansible package updates triggered"
      async: 1
      poll: 0
      ignore_errors: true
    - name: waiting for server to come back
      local_action: wait_for host={{ inventory_hostname }} state=started delay=30 timeout=300
      sudo: false
    - name: verify a reboot was actually initiated
      # uptime after reboot should be smaller than before reboot
      shell: (( `cat /proc/uptime | awk -F . '{print }'` < {{ uptime.stdout }} ))
      sudo: false
10
répondu akostadinov 2016-02-09 12:14:46

je voulais commenter sur Shahar post, qu'il utilise mieux une adresse hôte codée en dur, c'est d'avoir une variable pour référencer l'hôte actuel que ansible configure {{ inventory_hostname }}, donc son code sera comme ça:

- name: Wait for server to restart
  local_action:
    module: wait_for
     host={{ inventory_hostname }}
     port=22
     delay=1
     timeout=300
7
répondu Walid 2014-10-25 06:30:29

2018 mise à Jour

à partir de 2.3, Ansible embarque maintenant avec le wait_for_connection module, qui peut être utilisé pour exactement cet effet.

#
## Reboot
#

- name: (reboot) Reboot triggered
  command: /sbin/shutdown -r +1 "Ansible-triggered Reboot"
  async: 0
  poll: 0

- name: (reboot) Wait for server to restart
  wait_for_connection:
    delay: 75

le shutdown-r +1 empêche un code de retour de 1 d'être retourné et avoir une possibilité de manquer la tâche. L'arrêt est exécuté comme une tâche asynchrone, donc nous avons de retard wait_for_connection tâche d'au moins 60 secondes. 75 nous donne un tampon pour ces cas de flocons de neige.

wait_for_connection - Attend jusqu'à ce que le système distant est accessible/utilisable

7
répondu infrascripting 2018-02-08 17:58:07

avec les nouvelles versions D'Ansible (i.e. 1.9.1 dans mon cas), les paramètres poll et async mis à 0 sont parfois insuffisants (peut-être en fonction de quelle distribution est configuré ansible ?). Comme expliqué dans https://github.com/ansible/ansible/issues/10616 une solution de contournement est :

- name: Reboot
  shell: sleep 2 && shutdown -r now "Ansible updates triggered"
  async: 1
  poll: 0
  ignore_errors: true

Et puis, attendez le redémarrage complet comme expliqué dans de nombreuses réponses de cette page.

5
répondu amichaud 2015-07-26 21:29:53

par essais et erreurs + beaucoup de lecture c'est ce qui a finalement fonctionné pour moi en utilisant la version 2.0 D'Ansible:

$ ansible --version
ansible 2.0.0 (devel 974b69d236) last updated 2015/09/01 13:37:26 (GMT -400)
  lib/ansible/modules/core: (detached HEAD bbcfb1092a) last updated 2015/09/01 13:37:29 (GMT -400)
  lib/ansible/modules/extras: (detached HEAD b8803306d1) last updated 2015/09/01 13:37:29 (GMT -400)
  config file = /Users/sammingolelli/projects/git_repos/devops/ansible/playbooks/test-2/ansible.cfg
  configured module search path = None

ma solution pour désactiver SELinux et redémarrer un noeud en cas de besoin:

---
- name: disable SELinux
  selinux: state=disabled
  register: st

- name: reboot if SELinux changed
  shell: shutdown -r now "Ansible updates triggered"
  async: 0
  poll: 0
  ignore_errors: true
  when: st.changed

- name: waiting for server to reboot
  wait_for: host="{{ ansible_ssh_host | default(inventory_hostname) }}" port={{ ansible_ssh_port | default(22) }} search_regex=OpenSSH delay=30 timeout=120
  connection: local
  sudo: false
  when: st.changed

# vim:ft=ansible:
4
répondu slm 2015-09-03 18:51:53
- wait_for:
    port: 22
    host: "{{ inventory_hostname }}"
  delegate_to: 127.0.0.1
0
répondu Moriarty 2015-04-10 04:53:32

dans le cas où vous n'avez pas encore de configuration DNS pour le serveur distant, vous pouvez passer l'adresse IP au lieu d'une variable nom d'hôte:

- name: Restart server
  command: shutdown -r now

- name: Wait for server to restart successfully
  local_action:
    module: wait_for
      host={{ ansible_default_ipv4.address }}
      port=22
      delay=1
      timeout=120

Voici les deux tâches que j'ai ajoutées à la fin de mon ansible-swap playbook (pour l'installation de 4 go de swap sur de nouvelles Numérique de l'Océan gouttelettes.

0
répondu Aaron Tribou 2016-05-21 17:15:05