ansible的脚本中我们可能会要启动某项服务并等待,直到服务启动起来,然后再进行下一步

这个非常重要,我们举例来实验一下:

- 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'

上面的 playbook 一共有7步:

1、停止 ssh 服务

2、获取 ansible_fact 变量

3、断言 ansible_facts 中的 ssh 服务是 stopped 状态

4、重新启动 ssh 服务

5、断言 ansible_facts 中的 ssh 服务仍然是 stopped 状态

6、重新获取 ansible_fact 变量

7、这时 ansible_facts 中的 ssh 服务状态刷新了,变成了 running

就是服务启动后,必须去不断刷新 ansible_facts,才能获得刷新后的状态,所以我们利用这一点,脚本如下:

- hosts: localhost
  vars:
    local__service: ssh
  tasks:
    - 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

上面wait until的步骤就是,注册一个临时的变量,然后不断去测试,重试20次,每次的延时是2秒。这样就可以解决了。