Ansible - 如何在多个主机上循环并在找到正确答案时停止? [英] Ansible - How to loop over multiple hosts and stop when find correct answer?

查看:22
本文介绍了Ansible - 如何在多个主机上循环并在找到正确答案时停止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆