1

I'm using Ansible to update a pool of EC2 servers with a rolling update, in batches of 25%. In between batches, I'm pausing long enough for the server health checks to start to pass again (since they'll fail while the application server restarts).

The question is, can I skip the delay on the final pass so the playbook will finish sooner? Here is the script. The last line is the API I want:

---
- hosts: tag_deploy_environment_development
  serial: "25%"
  remote_user: ec2-user
  become: no
  vars:
    health_check_healthy_threshold: 2
    health_check_interval: 10
    server_port: 80
  tasks:
    #- debug: var=vars
    #- debug: var=ansible_facts

    - name: "Copy the current server version from disk"
      include_role:
        name: deploy-code
        tasks_from: push-files

    - name: "Wait for {{ server_port }} to become available"
      wait_for:
        port: "{{ server_port }}"
        timeout: 60
        state: started

    # I would like to check whether we are on the final batch,
    # and don't pause in that case:
    - pause:
        seconds: "{{ health_check_healthy_threshold * health_check_interval }}"
        prompt: Waiting to allow AWS health checks to pass
      when: ansible_facts['remaining_batches'] > 0
1

To solve this, I printed vars and ansible_facts, and eventually stumbled on the ansible_play_batch variable, which is a list of hostnames in the current batch. ansible_play_hosts_all gives the full list of hostnames. (Do not use ansible_play_hosts for this purpose, because as of Ansible 2.7, it works but the docs say it gives something completely different.)

The question: Is this the final batch?
Rephrasing based on the data: Is this batch == the last part of the host list?
Or to make it simpler: Is the end of this batch == the end of the host list?

In Ansible, the check for that is:

tasks:
  - pause:
      seconds: "{{ health_check_healthy_threshold * health_check_interval }}"
      prompt: Waiting to allow AWS health checks to pass
    when: ansible_play_batch[-1] != ansible_play_hosts_all[-1]

  - debug: msg="This is the last batch."
    when: ansible_play_batch[-1] == ansible_play_hosts_all[-1]

Side note: I used the following playbook for testing, to simulate having many/few hosts without bothering to set them up. I couldn't see how to specify the hosts as a list in the playbook, so I added them to a group, then executed the group:

---
- hosts: localhost
  connection: local
  tasks:
    - add_host: { name: host1, groups: test_hosts }
    - add_host: { name: host2, groups: test_hosts }
- hosts: test_hosts
  connection: local
  serial: "25%"
  tasks:
    - debug: var=ansible_play_batch

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.