HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Can I check whether ansible is on last batch of rolling update (serial: 25%)?

Submitted by: @import:stackexchange-devops··
0
Viewed 0 times
lastcanupdaterollingbatchserialcheckwhetheransible

Problem

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

Solution

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

Code Snippets

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

Context

StackExchange DevOps Q#6058, answer score: 3

Revisions (0)

No revisions yet.