0

This is for a set of hosts, where no more than one host with a service may be down at time and host's set up may be a complex routine. I already tried serial: 1 (it's Rolling Update in Ansible terms), --limit $host, --fork 1. All of them works in undesirable way: it still running play by play instead of host by host.

Here are current properties and desired ones for a solution (it's a matter of subject and it's possible to rewrite solution from scratch too):

  • I have set of playbooks - ready for use solution.
  • I want to run this solution against each host one by one.
  • Inventory is created with Python logic before a launch of a play (it's done).
  • Hosts already are spread across arbitrary set of groups. Certain hosts are only members of one group, certain host are members of another group only. I have dynamic inventory (Ansible Dynamic inventory feature) and in inventory always have auto-generated group with plain list of all hosts involved.

Looking for how to:

  • All plays should be ran at a first host and finish.
  • All plays should be ran at a second host and finish.
  • And so on at arbitrary quantity of hosts.
  • If a host is not from a group for a playbook, play should not be applied at this host.

Advise me please: How may I achieve it?

Below are simplified parts of the plays set. It have been created and generally it works.

My top level playbook site.yaml

---
-   name: Site set up
    hosts:
        - masters
        - replicas
    serial: 1
    roles:
        - role: do-01
        - role: do-02

-   import_playbook: play-do-11.yaml
-   import_playbook: play-do-12.yaml

I have play books: play-do-11.yaml, play-do-12.yaml like this:

---
-   name: play-do-11
    hosts: satellites
    serial: 1
    roles:
        -   role: actor

I'm starting Ansible playbook in this way:

for single_host in  host-a  host-b  host-c ; do
    ansible-playbook \
        --forks 1 \
        --limit "$single_host" \
        --inventory inventory.json \
        "site.yaml"
done

P.S. It's out of scope, but it adds flexibility to a solution I'm looking for. In fact I have dynamic inventory. It can be launched before any other items launch. There is auto-added group with plain list of all hosts in the inventory. Thus, I can create pre-generated Json and before a launch I have all host name's as plain strings. It is used in Shell launcher like this:

for host in $( cat inventory.json | jq -r ".\"group-with-all\".hosts | keys[]" ) ; do
    ansible-playbook --limit "${host}" ...
done

It's well enough for automation: hosts grouping and properties still are managed in one place.

  • Would it be possible to explain what does "a host match a group for this role" mean? Or, in other words, what does "a group for a role" mean? Shouldn't this be rather "a group for this play"? – Vladimir Botka Mar 22 at 14:54
  • Thank you! Fixed it, may be no need to mention this condition. Yes, in other words: If a host is not from a group for a playbook, play should not be applied at this host. – Charles_Ashley Mar 22 at 19:14
0

Q "All plays should be run at a first host and finish. All plays should be run at a second host and finish. And so on at arbitrary quantity of hosts."

A: It's not possible. The scope of serial and strategy is a play. All hosts shall complete a play before the next one could be started. An import of a playbook is equivalent to starting a new play.

Q: "If a host is not from a group for a playbook, play should not be applied at this host."

A: It's possible to create a new group in the first play and use it by the imported playbooks. For example the inventory

shell> cat hosts
[test]
test_01
test_02
test_03

[satellites]
test_03

and the playbook

shell> cat play-do-11.yml
- hosts: my_dynamic_group
  tasks:
    - debug:
        var: inventory_hostname

imported from the playbook

shell> cat site.yml
- hosts: test
  tasks:
    - add_host:
        name: "{{ item }}"
        groups: my_dynamic_group
      loop: "{{ groups.test }}"
      when: item in groups.satellites
      run_once: true
    - debug:
        var: inventory_hostname

- import_playbook: play-do-11.yml

gives

shell> ansible-playbook site.yml

PLAY [test] ***

TASK [add_host] ***
skipping: [test_01] => (item=test_01) 
skipping: [test_01] => (item=test_02) 
changed: [test_01] => (item=test_03)

TASK [debug] ***
ok: [test_01] => {
    "inventory_hostname": "test_01"
}
ok: [test_03] => {
    "inventory_hostname": "test_03"
}
ok: [test_02] => {
    "inventory_hostname": "test_02"
}

PLAY [my_dynamic_group] ***

TASK [debug] ***
ok: [test_03] => {
    "inventory_hostname": "test_03"
}

PLAY RECAP ***
| improve this answer | |

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.