Ansible-如何在多个主机上循环并在找到正确答案时停止?

Ansible-如何在多个主机上循环并在找到正确答案时停止?,ansible,Ansible,我想使用uri模块循环一组主机(它们在清单中),直到状态代码为200,然后将此主机名保存到变量中 下面写的完全错了,只是为了表达我的需要。 (注意:我在all_uri_group中有4台主机,我知道第二台和第三台主机的状态代码为200,我想停止第二台主机中的循环,并用第二台主机名的值注册有效的\u主机 -名称:查找有效主机 主持人:所有组 uri: url:https://{fa_url}}/api/{{api_version}}/volume 方法:邮寄 验证证书:否 返回内容:是 状态代码:

我想使用
uri
模块循环一组主机(它们在清单中),直到状态代码为
200
,然后将此主机名保存到变量中

下面写的完全错了,只是为了表达我的需要。
(注意:我在
all_uri_group
中有4台主机,我知道第二台和第三台主机的状态代码为
200
,我想停止第二台主机中的循环,并用第二台主机名的值注册
有效的\u主机

-名称:查找有效主机
主持人:所有组
uri:
url:https://{fa_url}}/api/{{api_version}}/volume
方法:邮寄
验证证书:否
返回内容:是
状态代码:200
登记:答复
直到:状态_代码==200
重试次数:0
延迟:0

但是我不知道如何正确地在Ansible中编写它。

由于基于前一个主机的返回值跳过主机的执行是非常棘手的,但是基于前一个返回在循环中跳过是非常容易的,您可以使用
Ansible\u play\u批处理
创建一个包含所有主机的循环n根据循环

下面是我设置3个节点的示例。
请注意,我故意使第一个节点无法根据您的要求看到它的反应

根据剧本:

-主机:所有
收集事实:不
任务:
-uri:
url:“http://example{{'dummy'如果item=='node1'else'}}.org“
状态代码:200
委托给:“{{item}}”
登记:答复
循环:{{ansible\u play\u hosts}}”
当:“reply.status |默认值(0)!=200”
跑一次:对
忽略错误:是
-设定事实:
所选主机:“{{item.item}”
循环:“{reply.results}}”
当:未跳过项且项状态==200时
跑一次:对
回路控制:
标签:“{item.item}”
-调试:
var:所选的\u主机
跑一次:对
这让我概括一下:

播放[全部]********************************************************************************************************
任务[uri]********************************************************************************************************
失败:[node1->node1](item=node1)=>changed=false
ansible_循环变量:项
已用时间:0
项目:节点1
msg:'状态代码为-1而不是[200]:请求失败:'
重定向:错误
状态:-1
网址:http://exampledummy.org
确定:[node1->node2]=>(项=node2)
跳过:[node1]=>(项=node3)
…忽略
任务[设置事实]***************************************************************************************************
跳过:[node1]=>(项=node1)
确定:[node1]=>(项=node2)
跳过:[node1]=>(项=node3)
任务[调试]******************************************************************************************************
确定:[节点1]=>
所选主机:node2
重演********************************************************************************************************
节点1:确定=3更改=0无法访问=0失败=0跳过=0获救=0忽略=1

我看不到一个简单的方法来满足您的确切要求(即浏览主机列表,在第一个主机正确回答时停止,并注册其名称)

这是我能想到的最接近的。请注意,我不是在循环中使用主机播放,而是在使用您的组的
uri
任务上使用特定的循环。想法是调用每个主机的url,然后打印列表中的第一个主机名,这会给出满意的答案

在下面的示例中,我想当然地认为
fa_url
api_version
是可以为组中的每个主机设置的变量,并且可以从localhost访问它们

-名称:查找第一个响应的主机
主机:本地主机
收集事实:错误
任务:
-名称:在每个主机上尝试uri,忽略错误
uri:
url:https://{{hostvar[item].fa_url}}/api/{{hostvar[item].api_version}/volume
方法:邮寄
验证证书:否
返回内容:是
状态代码:200
登记:答复
忽略错误:true
循环:“{groups.all_uri_group}”
-名称:打印第一个响应主机的名称
变量:
第一个_响应:{{(reply.results | select('success')| first.item}}”
msg:“第一个响应的主机是{{First_responding}}”

根据您的问题,不清楚您是否实际连接到主机上的url(即,
fa_url
对于每个主机都是不同的)了解服务是否在那里工作,或者您是否希望检查每个主机是否可以连接到外部服务。我正要发布第一个案例的解决方案,但将等待您的确认。Hi@Zeitounator抱歉,不清楚,是的,每个主机的fa_url不同(我指的是url IP),我想得到第一个具有工作服务的主机(因为服务是相同的)停止循环。希望清楚。谢谢。谢谢你的澄清。SO上的人们通常希望你澄清,而不是散布在易变的评论上。更清楚的问题有更多机会吸引更好更准确的答案。嗨@Zeitounator,很抱歉;下次会这样做,我是新来的;谢谢你你的提示和β.εηοιτ.βε的提示都起作用了!再次感谢@β.εηοιτ.βε-你的解决方案也起作用了!谢谢,这起作用了!非常感谢