Ansible - 如何在多个主机上循环并在找到正确答案时停止? [英] Ansible - How to loop over multiple hosts and stop when find correct answer?
问题描述
我想使用 uri
模块遍历一组主机(它们在库存中),直到状态代码为 200
,然后将此主机名保存到一个变量.
I would like to loop over a group of hosts (they are in inventory) with uri
module, only until the status code is 200
, and save this hostname to a variable.
下面写的完全错误,只是为了表达我的需要.
(注意:我在 all_uri_group
中有 4 个主机,我知道第二个和第三个的状态代码为 200
,我想在第二个主机中停止循环,并注册valid_host
带有第二个主机名的值.
What's written below is completely wrong, It's just to express my need.
(Note : I have 4 hosts in all_uri_group
, I know the 2nd and 3rd ones have the status code 200
, I want to stop the loop in 2nd host, and register the valid_host
with the value of second hostname.
- name: Looking for valid host
hosts: all_uri_group
uri:
url: https://{{ fa_url }}/api/{{ api_version }}/volume
method: POST
validate_certs: no
return_content: yes
status_code: 200
register: reply
until: status_code == 200
retries: 0
delay: 0
但我不知道如何在 Ansible 中正确编写它.
But I have no idea how to correctly write it in Ansible.
推荐答案
因为根据前一个主机的返回值跳过一个主机的执行是相当棘手的但是基于以前的返回很容易,您可以使用 特殊变量 ansible_play_batch
,然后是根据循环item
委托任务.
Since skipping the execution of a host based on the return value of a previous host is quite tricky but skipping in a loop based on a previous return is quite easy, you could create a loop with all the hosts in the play with the special variable ansible_play_batch
, then delegate the task according to the loop item
.
这是我设置的 3 个节点的示例.
请注意,根据您的要求,我故意让第一个节点无法看到它的反应.
Here is an example of my setting with 3 nodes.
Note that I am purposefully making the the first node fail to see how it reacts, based on your requirements.
给定剧本:
- hosts: all
gather_facts: no
tasks:
- uri:
url: "http://example{{ 'dummy' if item == 'node1' else '' }}.org"
status_code: 200
delegate_to: "{{ item }}"
register: reply
loop: "{{ ansible_play_hosts }}"
when: "reply.status | default(0) != 200"
run_once: true
ignore_errors: yes
- set_fact:
selected_host: "{{ item.item }}"
loop: "{{ reply.results }}"
when: item is not skipped and item.status == 200
run_once: true
loop_control:
label: "{{ item.item }}"
- debug:
var: selected_host
run_once: true
这给了我一个回顾:
PLAY [all] ********************************************************************************************************
TASK [uri] ********************************************************************************************************
failed: [node1 -> node1] (item=node1) => changed=false
ansible_loop_var: item
elapsed: 0
item: node1
msg: 'Status code was -1 and not [200]: Request failed: <urlopen error [Errno -2] Name does not resolve>'
redirected: false
status: -1
url: http://exampledummy.org
ok: [node1 -> node2] => (item=node2)
skipping: [node1] => (item=node3)
...ignoring
TASK [set_fact] ***************************************************************************************************
skipping: [node1] => (item=node1)
ok: [node1] => (item=node2)
skipping: [node1] => (item=node3)
TASK [debug] ******************************************************************************************************
ok: [node1] =>
selected_host: node2
PLAY RECAP ********************************************************************************************************
node1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
这篇关于Ansible - 如何在多个主机上循环并在找到正确答案时停止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!