首页 > 解决方案 > 如何在 Ansible 中读取复杂的包含变量

问题描述

我有一个变量文件,它在 IP 地址下列出了多个变量“名称”和“路径”,如下所示。

10.0.0.12
    - name: exe_folder
      path: /tmp/exe
    - name: log_folder
      path: /tmp/log
    - name: src_folder
      path: /tmp/src

10.0.0.13
    - name: test_folder
      path: /tmp/exe1
    - name: out_folder
      path: /tmp/log1
    - name: com_folder
      path: /tmp/src1

 etc ....

我可以在我的剧本中成功循环名称和路径,如下所示。

   - name: Load repository
     include_vars:
       file="{{ playbook_dir }}/vars/list.yml"
       name=user1

   - debug:
       msg: "{{ item.name + ':' + item.path }}"  
     loop: "{{ user1[inventory_hostname] }}"  

   - set_fact:
       allinonecmd: "{{ allinonecmd | default('') + 'ls -ltr ' + item.path + ' '}}"  
     loop: "{{ user1[inventory_hostname] }}"  

我的要求是在每个 IP 下都有一个新变量“mycode”,但是只需提及它,我应该能够像上面的剧本那样在循环中打印它。

因此,我需要我的变量文件为每个 IP 指定一次 mycode。我不确定我需要对我的变量文件和剧本进行哪些更改以适应此要求。

10.0.0.12
    - name: exe_folder
      path: /tmp/exe
      mycode: "56.12"
    - name: log_folder
      path: /tmp/log
    - name: src_folder
      path: /tmp/src

10.0.0.13
    - name: test_folder
      path: /tmp/exe1
      mycode: "76.88"
    - name: out_folder
      path: /tmp/log1
    - name: com_folder
      path: /tmp/src1

 etc ....

在我进行上述更改并尝试打印 mycode 变量后,剧本失败。

   - debug:
       msg: "{{ item.name + ':' + item.path + item.mycode }}"  
     loop: "{{ user1[inventory_hostname] }}"  

错误输出:

fatal: [10.0.0.12]: FAILED! => {
    "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'mycode'

注意:我不希望在一个 IP 下多次指定 mycode,因为它看起来像一个肮脏的解决方案。

标签: loopsvariablesansible

解决方案


我认为对于这个用例,您可以使用 default() 过滤器,因此如果此元素不在列表中,您可以调用默认值或省略它。

vars:
  my_default_value: "56.12"

   - debug:
       msg: "{{ item.name + ':' + item.path + (item.mycode | default(my_default_value) }}"       loop: "{{ user1[inventory_hostname] }}"  

甚至您可以组合使用 default(value) 和 default(omit) 来满足您的需求。


推荐阅读