在Ansible任务中的每个项目上选择带有条件的with_项目?

在Ansible任务中的每个项目上选择带有条件的with_项目?,ansible,yaml,ansible-2.x,Ansible,Yaml,Ansible 2.x,我有一个需要根据集群位置选择的代理列表。例如,我的集群名称是“abc”和“def”。集群上的所有节点都以集群名称开头(例如abc1023.net for abc等) 我想根据当前的inventory\u主机名为pip选择代理,并在参数中提供它。我尝试使用带有_项的映射,并按照以下代码在映射内“创建”when条件: -name:在代理上运行pip pip: 姓名: 额外参数:“--proxy item.proxy” 时间:“项目。时间” 有以下项目: -{proxy:'http:abc_proxy

我有一个需要根据集群位置选择的代理列表。例如,我的集群名称是“abc”和“def”。集群上的所有节点都以集群名称开头(例如abc1023.net for abc等)

我想根据当前的
inventory\u主机名
为pip选择代理,并在参数中提供它。我尝试使用带有_项的映射,并按照以下代码在映射内“创建”when条件:

-name:在代理上运行pip
pip:
姓名:
额外参数:“--proxy item.proxy”
时间:“项目。时间”
有以下项目:
-{proxy:'http:abc_proxy:port',当:{{inventory_hostname}中的'abc}
-{proxy:'http:def_proxy:port',当:{{inventory_hostname}中的'def}
我面临的问题是,这种情况总是被认为是正确的。我尝试将{inventory_hostname | lower}}中的“abc”替换为
when:false
,这确实有效。也就是说,将其设为显式false实际上会返回false,但在我检查字符串引号中的条件时不会返回false。我认为,如果地图中包含任何值,那么这一点就被认为是正确的

如何在when映射中显式检查此条件?删除引号没有帮助,因为它会引发语法错误:

  • 测试错误案例
    我在abc cluster上通过以下方式测试了错误案例:
  • -name:在代理上运行pip
    变量:
    abc_状态:{{{inventory_hostname}lower}else false}中的{true如果'abc'为}
    def_状态:“{{inventory_hostname}lower}else false}中的{true如果'def'为true”
    pip:
    姓名:
    额外参数:“--proxy item.proxy”
    时间:“项目。时间”
    有以下项目:
    -{proxy:'http:def_proxy:port',when:def_status}
    
    当代理和when条件在def集群上检查,而它在abc集群上运行时,这应该总是失败的。但我得到了以下可靠的输出:

    TASK [<project> : run pip on proxy] ************************************************
    changed: [abc1023.net] => (item={u'when': u'def_status', u'proxy': u'http:def_proxy:port'})
    
    TASK[:在代理上运行pip]************************************************
    更改:[abc1023.net]=>(项={u'when':u'def_status',u'proxy':u'http:def_proxy:port'})
    
    这也是我在其他尝试过的解决方案中得到的结果

    问题: 即使尝试了以上不同的解决方案,
    when:“item.when”
    始终返回true(即使它应该返回false)。我怎样才能解决这个问题?有没有更好的解决方案来实现我的用例? 为了完整性,我使用ansible 2.4.1.0。

    TL;博士 在这里,您试图评估字符串
    项。当“
    是一个布尔值,它是
    真的
    ,因为非空字符串将导致一个
    真的
    语句。
    删除
    when
    条件周围的双引号,您就可以开始了


    您从Ansible得到的警告是关于
    when
    的,并且只有这条语句,它始终是原始的Jinja2表达式

    这在Ansible with the when子句中很容易做到,包含一个没有双花括号的原始Jinja2表达式(请参阅)

    资料来源:,重点,我的

    根据您的实际情况,一个可能的解决方案是:

    -name:在代理上运行pip
    pip:
    姓名:
    额外参数:“--proxy{{item.proxy}”
    时间:库存中的item.proxy_ref_主机名|较低
    有以下项目:
    -代理:“http:abc\u代理:端口”
    代理参考:“abc”
    -代理:“http:def_代理:端口”
    代理_ref:'def'
    
    另一个可能是:

    -name:在代理上运行pip
    pip:
    姓名:
    额外参数:“--proxy{{item.proxy}”
    时间:item.when
    有以下项目:
    -代理:“http:abc\u代理:端口”
    当:“{{abc'在目录{u主机名}下}”
    -代理:“http:def_代理:端口”
    当:{{inventory_hostname中的'def}}
    
    因此,简而言之,在这里,您试图评估字符串
    项。当“
    是一个布尔值,它是
    真的
    ,因为非空字符串将导致
    真的
    语句。
    删除
    when
    条件周围的双引号,您就可以开始了

    PS:尽可能不要将JSON语法与YAML语法混用

    问:“有没有更好的解决方案来实现我的用例?”

    答:使用代理的串联可能会更好。比如说

    -name:在代理上运行pip
    pip:
    名称:“{package_name}}”
    额外参数:“--proxy{{my_proxy}”
    变量:
    my_前缀:“{{inventory_主机名[0:3]}”
    my_proxy:“{{'http:'~my_prefix~''\u proxy:port'}}”
    
    TASK [<project> : run pip on proxy] ************************************************
    changed: [abc1023.net] => (item={u'when': u'def_status', u'proxy': u'http:def_proxy:port'})