How to make Ansible run batch of tasks on few nodes but one by one (nodes running in cluster)

You can place all recurring tasks in a block. Combined with serial: 1 you make sure that only one block is executed at a time.

- hosts: nodes
  serial: 1
  tasks:
    - name: get cluster state 
      shell: "RESTAPI 1 command"
      run_once: yes
    - name: put cluster in upgrade mode
      shell: "RESTAPI 2 command"
      run_once: yes
    - block:
      - name: upgrade Apache
        shell: "upgrade Apache command"
      - name: start Apache
        shell: "start Apache command"
      - name: healthy check for Apache is running
        shell: "RESTAPI command"
#       retries: 20
#       delay: 15

I'm assuming that the command to put the cluster in upgrade mode can be run on any node, so you can just use run_once. If this is not the case and it has to be run on a specific node you could use a when restriction for a specific host.

For the health check the parameters delay and retries could be of interest, if the possibility exists that the check fails at first and succeeds when apache is fully running.

To use the playbook on different host groups you could use hosts: all and then limit the hosts to a group during execution.

ansible-playbook upgrade.yml --limit dev_nodes