没有什么能阻止你在剧本中进行多次剧本:
- hosts: all
gather_facts: no
tasks:
- debug:
msg: "{{ my_var }}"
- hosts: host2
gather_facts: no
tasks:
- debug:
msg: "{{ my_var }}"
# ^--- Off course, now the when become superfluous,
# since we target a host that we know have those conditions
- hosts: all
gather_facts: no
tasks:
- debug:
msg: "Keep on going with all hosts"
回顾一下:
PLAY [all] **********************************************************************************************************
TASK [debug] ********************************************************************************************************
ok: [host1] => {
"msg": {
"one": true,
"two": "master"
}
}
ok: [host2] => {
"msg": {
"one": false,
"two": "master"
}
}
ok: [host3] => {
"msg": {
"one": false,
"two": "master"
}
}
ok: [host4] => {
"msg": {
"one": false,
"two": "arbiter"
}
}
PLAY [host2] ********************************************************************************************************
TASK [debug] ********************************************************************************************************
ok: [host2] => {
"msg": {
"one": false,
"two": "master"
}
}
PLAY [all] **********************************************************************************************************
TASK [debug] ********************************************************************************************************
ok: [host1] => {
"msg": "Keep on going with all hosts"
}
ok: [host2] => {
"msg": "Keep on going with all hosts"
}
ok: [host3] => {
"msg": "Keep on going with all hosts"
}
ok: [host4] => {
"msg": "Keep on going with all hosts"
}
PLAY RECAP **********************************************************************************************************
host1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host2 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host4 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
或者,对于更动态的解决方案,您可以选择正确的主机,通过魔术变量 hostvars 循环访问主机变量,然后使用 delegate_to 将任务委托给该主机。
鉴于剧本:
- hosts: all
gather_facts: no
tasks:
- set_fact:
host_master_not_one: "{{ item }}"
when:
- host_master_not_one is not defined
- not hostvars[item].my_var.one
- "'master' == hostvars[item].my_var.two"
run_once: true
loop: "{{ ansible_play_hosts }}"
- debug:
msg: "Running only once, on host {{ host_master_not_one }}"
delegate_to: "{{ host_master_not_one }}"
run_once: true
它给出了回顾:
PLAY [all] **********************************************************************************************************
TASK [set_fact] *****************************************************************************************************
skipping: [host1] => (item=host1)
ok: [host1] => (item=host2)
skipping: [host1] => (item=host3)
skipping: [host1] => (item=host4)
TASK [debug] ********************************************************************************************************
ok: [host1 -> host2] => {
"msg": "Running only once, on host host2"
}
PLAY RECAP **********************************************************************************************************
host1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
此回顾的重要部分是 [host1 -> host2],它表示任务已被委派,因此在 host2 上运行。
甚至,在同样的思路上,跳过与具有上述条件的主机不匹配的主机:
- hosts: all
gather_facts: no
tasks:
- set_fact:
host_master_not_one: "{{ item }}"
when:
- host_master_not_one is not defined
- not hostvars[item].my_var.one
- "'master' == hostvars[item].my_var.two"
run_once: true
loop: "{{ ansible_play_hosts }}"
- debug:
msg: "Running only once, on host {{ host_master_not_one }}"
when: inventory_hostname == host_master_not_one
回顾一下:
PLAY [all] **********************************************************************************************************
TASK [set_fact] *****************************************************************************************************
skipping: [host1] => (item=host1)
ok: [host1] => (item=host2)
skipping: [host1] => (item=host3)
skipping: [host1] => (item=host4)
TASK [debug] ********************************************************************************************************
skipping: [host1]
ok: [host2] => {
"msg": "Running only once, on host host2"
}
skipping: [host3]
skipping: [host4]
PLAY RECAP **********************************************************************************************************
host1 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
host2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
host3 : ok=0 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
host4 : ok=0 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0