Categories
DevOps

How to wait until service is running inside ansible playbook

Wait until service is stopped or running inside ansible playbook.

Sample playbook to visualize the solution.

---
- hosts: localhost
  vars:
    local__service: ssh
  tasks:
    - block:
      - name: "Stop {{ local__service }} service"
        systemd:
          service: "{{ local__service }}"
          state: stopped

      - name: "Populate ansible_facts.services variable"
        ansible.builtin.service_facts:

      - name: "{{ local__service }} state will be stopped as expected"
        assert:
          that:
            ansible_facts.services[local__service].state == 'stopped'

      - name: "Start {{ local__service }} service"
        systemd:
          service: "{{ local__service }}"
          state: started

      - name: "Registered {{ local__service }} state will still be stopped as it was not refreshed"
        assert:
          that:
            ansible_facts.services[local__service].state == 'stopped'

      - name: "Refresh ansible_facts.services variable"
        ansible.builtin.service_facts:

      - name: "{{ local__service }} state will be running as expected"
        assert:
          that:
            ansible_facts.services[local__service].state == 'running'


    - block:
      - name: "Stop {{ local__service }} service"
        systemd:
          service: "{{ local__service }}"
          state: stopped

      - name: "Wait until {{ local__service }} service is stopped"
        ansible.builtin.service_facts:
        register: temp__service_facts
        until: temp__service_facts.ansible_facts.services[local__service].state == 'stopped'
        retries: 20
        delay: 2

      - name: "Start {{ local__service }} service"
        systemd:
          service: "{{ local__service }}"
          state: started

      - name: "Wait until {{ local__service }} service is running"
        ansible.builtin.service_facts:
        register: temp__service_facts
        until: temp__service_facts.ansible_facts.services[local__service].state == 'running'
        retries: 20
        delay: 2

Execute the above playbook.

$ ansible-playbook --become playbook.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
                                       
PLAY [localhost] *******************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************
ok: [localhost]

TASK [Stop ssh service] ************************************************************************************************************************************
changed: [localhost]

TASK [Populate ansible_facts.services variable] ************************************************************************************************************
ok: [localhost]

TASK [ssh state will be stopped as expected] ***************************************************************************************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Start ssh service] ***********************************************************************************************************************************
changed: [localhost]

TASK [Registered ssh state will still be stopped as it was not refreshed] **********************************************************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Refresh ansible_facts.services variable] *************************************************************************************************************
ok: [localhost]

TASK [ssh state will be running as expected] ***************************************************************************************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Stop ssh service] ************************************************************************************************************************************
changed: [localhost]

TASK [Wait until ssh service is stopped] *******************************************************************************************************************
ok: [localhost]

TASK [Start ssh service] ***********************************************************************************************************************************
changed: [localhost]

TASK [Wait until ssh service is running] *******************************************************************************************************************
ok: [localhost]

PLAY RECAP *************************************************************************************************************************************************
localhost                  : ok=12   changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

There are two blocks. The first one is to show how to use ansible.builtin.service_facts, the second one how to wait for a specific service state.