Answers: <p>To solve this, I printed <code>vars</code> and <code>ansible_facts</code>, and eventually stumbled on the <code>ansible_play_batch</code> variable, which is a list of hostnames in the current batch. <code>ansible_play_hosts_all</code> gives the full list of hostnames. (Do not use <code>ansible_play_hosts</code> for this purpose, because as of Ansible 2.7, it works but <a href="https://docs.ansible.com/ansible/2.7/reference_appendices/special_variables.html" rel="nofollow noreferrer">the docs</a> say it gives something completely different.)</p>
  
  <p>The question: Is this the final batch?<br>
  Rephrasing based on the data: Is this batch == the last part of the host list?<br>
  Or to make it simpler: Is the end of this batch == the end of the host list?</p>
  
  <p>In Ansible, the check for that is:</p>
  
  <pre><code>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]
  </code></pre>
  
  <hr>
  
  <p>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:</p>
  
  <pre><code>---
  - 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
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2019-01-22T06:36:52.647Z
Answers: 2019-06-22T16:06:33.377Z
Answers: 2019-06-22T16:06:33.377Z
Answers: piojo
Body: <p>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).</p>
  
  <p>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:</p>
  
  <pre><code>---
  - 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'] &gt; 0
  </code></pre>
  
Tags: <amazon-web-services><ansible><amazon-ec2><ansible-inventory>
Title: Can I check whether ansible is on last batch of rolling update (serial: 25%)?
UserDisplayName: piojo
ThreadText: # Can I check whether ansible is on last batch of rolling update (serial: 25%)?
  
  (Asked by: username_0 on 2019-01-22)
  
  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
  
  ```
  
  **Tags:** amazon-web-services, ansible, amazon-ec2, ansible-inventory
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2019-01-22. Score: 4
  
  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](https://docs.ansible.com/ansible/2.7/reference_appendices/special_variables.html) 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
  
  ```
  
  
  ---
  
  