0

我正在处理嵌套循环,以便使用 add_host 构建动态主机。

Outer Loop:      with_items: "{{ command_result.stdout_lines }}"  // gets me the list of users
Inner Loop:      with_items: "{{ dest_ip.split(',') }}"          // gets me the list of IP addresses seperated by comma (,)

下面的剧本工作正常。

   - name: Add hosts
     include_tasks: "{{ playbook_dir }}/gethosts.yml"
     vars:
       dest_ip: "{{ item.split('\t')[0] }}"
       file_dets: "{{ item.split('\t')[1] }}"
       USER_pass: "anystring"
#       USER_pass:  "{% if item.split('\t')[3] == 'FrontEnd' %}user1{% elif item.split('\t')[3] == 'BackEnd' %}user2{% else %}{% endif %}"
       ansible_host: localhost
       install_dir_pass: "anystring"
#       install_dir_pass: "{{ item.split('\t')[2] }}"

     with_items: "{{ command_result.stdout_lines }}"

下面是我的 include_task gethost.yml 文件:

---
 - name: Generate JSON data
    add_host:
      name: "{{ item }}"
      groups: dest_nodes
      ansible_user: "{{ USER_pass }}"
      install_dir: "{{ install_dir_pass }}"
    with_items: "{{ dest_ip.split(',') }}"

如果我取消注释 USER_pass 或 install_dir_pass 并注释现有值,则会收到以下错误:

任务 [生成 JSON 数据] ******************************************** ****************************************************** ************************************* 任务路径:/app/deployment/gethosts.yml:2 [警告]:循环变量 'item' 已在使用中。您应该将任务选项中的loop_var值设置为loop_control其他值,以避免变量冲突和意外行为。

致命的:[本地主机]:失败!=> { "msg": "该任务包含一个带有未定义变量的选项。错误是:列表对象没有元素 2\n\n错误似乎在 '/app/deployment/gethosts.yml':第 2 行,第 4 列,但可能\n位于文件中的其他位置,具体取决于确切的语法问题。\n\n违规行似乎是:\n\n---\n - name: Generate JSON data\n
^ here\n " }

没有更多的主机了


播放回顾 ************************************************ ****************************************************** ************************************************ 本地主机:好的=12 更改=1 无法访问=0
失败=1 跳过=0 获救=0 忽略=0

请求解决此问题并解释我的一些问题。

  1. 当 install_dir_pass 等其他变量似乎不起作用时,dest_ip 被读取并与 include_task get_hosts.yml 文件中的 .split(,) 方法一起正常工作。

  2. 当 USER_pass 和 install_dir_pass 被赋予简单的字符串“AnyString”时,它可以工作并且在 get_hosts.yml 中可以很好地读取,就像使用 item.split('\t')[] 为它们分配值一样,上面的剧本错误。

我已经使用调试测试了 command_result 中的所有条目都很好,并且应该正确填充值,如下所示。

   - debug:
          msg: "{{  item.split('\t')[0]  }}"
         # msg: "{{  item.split('\t')[1]  }}"
          #msg: "{{  item.split('\t')[2]  }}"
       #   msg: "{{  item.split('\t')[3]  }}"
     with_items: "{{ command_result.stdout_lines }}"
4

1 回答 1

0

因为这在您的错误消息中得到了很好的解释:

  • item每个嵌套循环之间存在名称冲突。
  • 您必须loop_var在选项中设置名称loop_control以解决任一循环中的冲突。

我建议您在 上执行此操作,include_task以便解决包含文件中任何其他循环的问题。由于我不知道您的command_result.stdout_lines确切内容,我在下面的示例中使用了my_result您应该根据您的情况更改的 var 名称。请注意,如有必要,此 var 将直接在包含的文件中可用。

   - name: Add hosts
     include_tasks: "{{ playbook_dir }}/gethosts.yml"
     vars:
       dest_ip: "{{ my_result.split('\t')[0] }}"
       file_dets: "{{ my_result.split('\t')[1] }}"
       USER_pass:  "{% if my_result.split('\t')[3] == 'FrontEnd' %}user1{% elif my_result.split('\t')[3] == 'BackEnd' %}user2{% else %}{% endif %}"
       ansible_host: localhost
       install_dir_pass: "{{ my_result.split('\t')[2] }}"
     with_items: "{{ command_result.stdout_lines }}"
     loop_control:
       loop_var: my_result
于 2019-09-26T13:56:07.460 回答